Compare commits
619
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ed4e17c819 | ||
|
|
cbef2157d8 | ||
|
|
ee1e53b510 | ||
|
|
65757d1c4e | ||
|
|
cc5b5bc8a8 | ||
|
|
375c5a42db | ||
|
|
7de9e35dcf | ||
|
|
4c0fa08401 | ||
|
|
4e3ff8defc | ||
|
|
5d96114777 | ||
|
|
2ad1ef393a | ||
|
|
a22f6b64d9 | ||
|
|
28a2c8ca2b | ||
|
|
9d550cfaf1 | ||
|
|
93ab4802e9 | ||
|
|
df6fe473b3 | ||
|
|
679028e44e | ||
|
|
ecc43a436d | ||
|
|
2235fc7230 | ||
|
|
0ceaafda8f | ||
|
|
95e659a915 | ||
|
|
fe2eb099c5 | ||
|
|
686dede802 | ||
|
|
638e5b89db | ||
|
|
2c75dcaf69 | ||
|
|
6baaa9131f | ||
|
|
8c2dd49e80 | ||
|
|
f034a80c09 | ||
|
|
e47cfd8f4e | ||
|
|
b8e9e75c99 | ||
|
|
95ebcaf703 | ||
|
|
a46a25b491 | ||
|
|
2cd52da85d | ||
|
|
3523f43d20 | ||
|
|
39bd5367b5 | ||
|
|
258c9d0a8f | ||
|
|
97879e5956 | ||
|
|
72c0996b74 | ||
|
|
beea8a21e5 | ||
|
|
1409e02187 | ||
|
|
4a6ee0ea9d | ||
|
|
9504b624ee | ||
|
|
4d716bcdcf | ||
|
|
49606fb02f | ||
|
|
3d00137047 | ||
|
|
a15e9d1c58 | ||
|
|
8b4db5fe83 | ||
|
|
1bb480309d | ||
|
|
787bcc53d4 | ||
|
|
2db5dab3cd | ||
|
|
8c3cfb7632 | ||
|
|
44abb2fa83 | ||
|
|
82afd32d93 | ||
|
|
89089be1d2 | ||
|
|
a6a9583b5b | ||
|
|
13209d3155 | ||
|
|
4e10d97b5a | ||
|
|
d06cb292fe | ||
|
|
7eb9477d9e | ||
|
|
16f33b5b9d | ||
|
|
32568ed13e | ||
|
|
721af4ccb8 | ||
|
|
54e92c973a | ||
|
|
88e0311a1f | ||
|
|
f8730791b9 | ||
|
|
8889011e5b | ||
|
|
5f505d5ab6 | ||
|
|
5d762fb206 | ||
|
|
3d6dcc3ae5 | ||
|
|
265616e997 | ||
|
|
b9339cd272 | ||
|
|
792c216c96 | ||
|
|
a90cce73b9 | ||
|
|
de90d0cd70 | ||
|
|
a3db288a7a | ||
|
|
f46480a987 | ||
|
|
5c0a84f7ed | ||
|
|
8d70d48591 | ||
|
|
7b6397b858 | ||
|
|
e5c2519fea | ||
|
|
5bc88faf4f | ||
|
|
b820e0070d | ||
|
|
8d5e782079 | ||
|
|
5679c79011 | ||
|
|
6a461dec0c | ||
|
|
714732df5a | ||
|
|
a3f8afbe63 | ||
|
|
650703c5c2 | ||
|
|
d86b4d51ef | ||
|
|
4bb265b431 | ||
|
|
d6ce9abef7 | ||
|
|
d3fda0e834 | ||
|
|
44435691c0 | ||
|
|
87888213da | ||
|
|
4c42d1bf74 | ||
|
|
aea19f70ef | ||
|
|
434d542c3c | ||
|
|
fa5d17a403 | ||
|
|
2952aa5a64 | ||
|
|
6e1d5830b5 | ||
|
|
c46a9c35dc | ||
|
|
db859e185e | ||
|
|
193a752f1a | ||
|
|
3eac19cf44 | ||
|
|
d724982acc | ||
|
|
dfd9f6efb3 | ||
|
|
d55488ae37 | ||
|
|
3ba15df875 | ||
|
|
4f581306d7 | ||
|
|
8f77053f51 | ||
|
|
0e05eedade | ||
|
|
4bceb2b4ba | ||
|
|
655fb4f149 | ||
|
|
ef3c770451 | ||
|
|
dddd3fe8c8 | ||
|
|
e4da425b23 | ||
|
|
8f72b6a97c | ||
|
|
73a3aa9286 | ||
|
|
7435f48389 | ||
|
|
f3f23a3018 | ||
|
|
c87d28b343 | ||
|
|
42a9a4be5d | ||
|
|
cb4d2af8d3 | ||
|
|
457e870330 | ||
|
|
6314406701 | ||
|
|
8a9614d19e | ||
|
|
3e534bbb39 | ||
|
|
e7d4743cba | ||
|
|
7f9d01a3b6 | ||
|
|
b1ed8ecfe9 | ||
|
|
56538221f3 | ||
|
|
c713834954 | ||
|
|
774df05998 | ||
|
|
dbe1401455 | ||
|
|
9141741b78 | ||
|
|
e1d6a2c192 | ||
|
|
88b7c11a23 | ||
|
|
4ba60c2c9d | ||
|
|
e1f2c9c57f | ||
|
|
04d7fec493 | ||
|
|
90e146e424 | ||
|
|
f0ecc4c996 | ||
|
|
912957c44e | ||
|
|
ec7148175b | ||
|
|
b35ea39a95 | ||
|
|
a6acdcb30b | ||
|
|
c20c8aa7ab | ||
|
|
8b3da0d297 | ||
|
|
912342ae0a | ||
|
|
2fe1e05591 | ||
|
|
22f7e7f3f7 | ||
|
|
5e409c1eb2 | ||
|
|
e40a9989ab | ||
|
|
94c215d36e | ||
|
|
d91dafc1c4 | ||
|
|
05d45022b1 | ||
|
|
07845cfcee | ||
|
|
86efba2cd5 | ||
|
|
307e9e6569 | ||
|
|
88e33282db | ||
|
|
a0e40919a7 | ||
|
|
9da300ae60 | ||
|
|
36c5fb549c | ||
|
|
083c63bb9c | ||
|
|
739b8c56f9 | ||
|
|
87db3621c6 | ||
|
|
0648867921 | ||
|
|
41b9b8bc3d | ||
|
|
20b68d6a23 | ||
|
|
0de657f09c | ||
|
|
db038aa7a7 | ||
|
|
56928ac206 | ||
|
|
a9d79b99b8 | ||
|
|
7ab7d572b9 | ||
|
|
887a75c1b1 | ||
|
|
157ec407e2 | ||
|
|
7513ce61ed | ||
|
|
7555818753 | ||
|
|
323088c4bd | ||
|
|
ccce44dfc0 | ||
|
|
a5ca6fdcfd | ||
|
|
466426a58f | ||
|
|
4873c5e8b9 | ||
|
|
078eb4fcf0 | ||
|
|
09cc76eb8d | ||
|
|
9ff489546c | ||
|
|
1d82ed8823 | ||
|
|
d537778b60 | ||
|
|
1d13a892fc | ||
|
|
4e7f84111d | ||
|
|
6b31718138 | ||
|
|
e9c0281404 | ||
|
|
66ea4e3e51 | ||
|
|
c9e2263325 | ||
|
|
1ceda34c43 | ||
|
|
467e64574f | ||
|
|
438fdc8686 | ||
|
|
dfd9c420d3 | ||
|
|
fb376c0ea0 | ||
|
|
ea66f4456f | ||
|
|
6a3a0dc201 | ||
|
|
b6e382e58f | ||
|
|
c7e9ec0a26 | ||
|
|
f4c1b73f28 | ||
|
|
f697420db8 | ||
|
|
7c7a08a3ca | ||
|
|
86e0cf46c6 | ||
|
|
a52816299d | ||
|
|
70f3028cdb | ||
|
|
f394bb15f9 | ||
|
|
4965e74d66 | ||
|
|
83561682eb | ||
|
|
d0f3f76f7e | ||
|
|
88e9b8bade | ||
|
|
09e4c08f28 | ||
|
|
c9d94545f8 | ||
|
|
68d29ef04e | ||
|
|
5d5cd5fd6d | ||
|
|
dc26321bab | ||
|
|
6bd6e91606 | ||
|
|
043c66ccfb | ||
|
|
121b33f8ed | ||
|
|
bf3136490d | ||
|
|
a6d25afa27 | ||
|
|
53d2731849 | ||
|
|
e2cfd88ac0 | ||
|
|
6004494e21 | ||
|
|
aee774b894 | ||
|
|
cd1f846f49 | ||
|
|
ffa41d78df | ||
|
|
4d5d695c75 | ||
|
|
cbf96ebbe5 | ||
|
|
96013db9aa | ||
|
|
c373d6fbc0 | ||
|
|
4b231d97ec | ||
|
|
416674e3ec | ||
|
|
f89b946d37 | ||
|
|
ae48970f5f | ||
|
|
ebb8282091 | ||
|
|
76ddf4dd35 | ||
|
|
f6ad3344f8 | ||
|
|
e6994e4e4e | ||
|
|
0e4b51c387 | ||
|
|
19700e8590 | ||
|
|
743b6a4774 | ||
|
|
dc10818143 | ||
|
|
2a7a700051 | ||
|
|
5f85f3c5d7 | ||
|
|
2d3a7a22f8 | ||
|
|
043e10f674 | ||
|
|
357c869a34 | ||
|
|
db8585b558 | ||
|
|
64a28c9842 | ||
|
|
cc519e3806 | ||
|
|
6733205d58 | ||
|
|
23ee0f028d | ||
|
|
6e76a35943 | ||
|
|
86881bef6e | ||
|
|
75ff922b6e | ||
|
|
af327950bd | ||
|
|
117ef7d826 | ||
|
|
6c815b2958 | ||
|
|
05b822d9c0 | ||
|
|
985bc55fa5 | ||
|
|
b5a782bb38 | ||
|
|
2e56ba9719 | ||
|
|
6adf694f74 | ||
|
|
f0b23d345a | ||
|
|
2391aaa7ec | ||
|
|
8ffb83e373 | ||
|
|
3f63753b63 | ||
|
|
30957daf40 | ||
|
|
748eb686ae | ||
|
|
3cefd5b142 | ||
|
|
9ac4e37847 | ||
|
|
da0fc54f91 | ||
|
|
20afeb186b | ||
|
|
ee852c6600 | ||
|
|
53d1be5349 | ||
|
|
4bdbb0da6f | ||
|
|
923da11ab4 | ||
|
|
914d0aa39d | ||
|
|
cc998c05ce | ||
|
|
c5027788ea | ||
|
|
f9ce771954 | ||
|
|
da0186c739 | ||
|
|
0ab4a8bd2d | ||
|
|
9a540fa54a | ||
|
|
ce694baef1 | ||
|
|
9f7bbc25a0 | ||
|
|
0634ffb8ee | ||
|
|
a9c9a9182e | ||
|
|
7cfd6851f6 | ||
|
|
7bdb045272 | ||
|
|
09ffe7dea8 | ||
|
|
44161d2ad2 | ||
|
|
340342faf8 | ||
|
|
d93c1ab3d6 | ||
|
|
35f845168b | ||
|
|
42436f754d | ||
|
|
5201f14173 | ||
|
|
088ff307c0 | ||
|
|
2abc23ac65 | ||
|
|
c0e556b167 | ||
|
|
d653e32e7b | ||
|
|
b74b92920e | ||
|
|
caba4b086a | ||
|
|
12bbe948b2 | ||
|
|
bc94080332 | ||
|
|
1da17a282c | ||
|
|
2f9a6eb588 | ||
|
|
1fd2f16726 | ||
|
|
5a70fd6940 | ||
|
|
09fe972366 | ||
|
|
725181de4a | ||
|
|
fd0ea3f2d7 | ||
|
|
675e09a1a7 | ||
|
|
b5a308dd11 | ||
|
|
8f9b91d3b3 | ||
|
|
129736f281 | ||
|
|
728567c778 | ||
|
|
9424d19106 | ||
|
|
86e9d3706b | ||
|
|
986d78cc91 | ||
|
|
dc29b84cdf | ||
|
|
4e410efbab | ||
|
|
6cbe7e6e56 | ||
|
|
cc90d39205 | ||
|
|
69645cb07b | ||
|
|
59ad970ad5 | ||
|
|
c428fc5e91 | ||
|
|
b812d1d30f | ||
|
|
67cc8f13af | ||
|
|
588fef1c4a | ||
|
|
d784daf884 | ||
|
|
7ebf431c87 | ||
|
|
e2a442b592 | ||
|
|
edbe592478 | ||
|
|
610b97b93e | ||
|
|
f6eaff7878 | ||
|
|
77c602c8f4 | ||
|
|
f5cdae1a41 | ||
|
|
f9f055bee1 | ||
|
|
6eb2d11eeb | ||
|
|
0d58e6fb2d | ||
|
|
ae7fcc1557 | ||
|
|
fad32cd820 | ||
|
|
4844041b1b | ||
|
|
9eea950d57 | ||
|
|
ab450c1181 | ||
|
|
2c6088c200 | ||
|
|
06757ff31f | ||
|
|
f2644db6d8 | ||
|
|
f29a69b8a1 | ||
|
|
0d1840da96 | ||
|
|
a2afa67d47 | ||
|
|
d7d951542d | ||
|
|
da42769160 | ||
|
|
2d91f0ee7d | ||
|
|
a81b9554c0 | ||
|
|
2d42cbd678 | ||
|
|
275624591c | ||
|
|
50b1a6144b | ||
|
|
ab52f79034 | ||
|
|
0f50991288 | ||
|
|
245e6202d2 | ||
|
|
18fbec23e4 | ||
|
|
fabd85a65e | ||
|
|
24a5e6dbbb | ||
|
|
26673d0ae0 | ||
|
|
e98e2d716c | ||
|
|
8b2621a4d1 | ||
|
|
b739f358f8 | ||
|
|
e43f4c6970 | ||
|
|
f769385853 | ||
|
|
80a7736199 | ||
|
|
a1d70f5bd0 | ||
|
|
143ee934b8 | ||
|
|
098c1fd73a | ||
|
|
d0b4d3d4dd | ||
|
|
4e0e6a1418 | ||
|
|
ebb36fb85c | ||
|
|
36793a4ea5 | ||
|
|
03fd135593 | ||
|
|
476e97c993 | ||
|
|
5392db8ecb | ||
|
|
ea1457231e | ||
|
|
57cbd57139 | ||
|
|
2b3b1c6f5b | ||
|
|
5618cfc8cf | ||
|
|
4490b6ef76 | ||
|
|
0217ce354b | ||
|
|
e1796cc858 | ||
|
|
319b397419 | ||
|
|
28ed7005dd | ||
|
|
cfc80b34a4 | ||
|
|
9744a2e2d0 | ||
|
|
e6dad5b25e | ||
|
|
5a8540804e | ||
|
|
655397547f | ||
|
|
930447a78c | ||
|
|
c1a70e67e5 | ||
|
|
de2ba94933 | ||
|
|
77ba9deee1 | ||
|
|
614ebb8d1b | ||
|
|
4bbbd0f8bc | ||
|
|
866254de0e | ||
|
|
6e74203857 | ||
|
|
1d8b50d5ac | ||
|
|
0e4b111dff | ||
|
|
6fc828a9ce | ||
|
|
58bf83f755 | ||
|
|
8ca448ddca | ||
|
|
39f8c1d134 | ||
|
|
69ffaa677e | ||
|
|
3de5bc5c39 | ||
|
|
9a4ccf4040 | ||
|
|
3a23fb4533 | ||
|
|
8c4200c888 | ||
|
|
6f0e43cab2 | ||
|
|
b514a3c5e0 | ||
|
|
6858e21d47 | ||
|
|
5e8e17b96a | ||
|
|
52462b45e9 | ||
|
|
c1ae90cea3 | ||
|
|
f27af1d3d2 | ||
|
|
ca55354034 | ||
|
|
5423b261f9 | ||
|
|
fd83e98e6c | ||
|
|
80caa785e2 | ||
|
|
25fc2d92e8 | ||
|
|
f04f14ff01 | ||
|
|
c4008bf8f3 | ||
|
|
c51fb5e22f | ||
|
|
134f7864fa | ||
|
|
2844bbfe1c | ||
|
|
f8ad688359 | ||
|
|
2bcb4e3366 | ||
|
|
4d1b58ccb3 | ||
|
|
73da2fea01 | ||
|
|
3e13f7a6d6 | ||
|
|
0c13beddb9 | ||
|
|
19eb56e374 | ||
|
|
7322aa96bd | ||
|
|
0c676afe1f | ||
|
|
989346aba2 | ||
|
|
d535c2a85e | ||
|
|
5252a236fc | ||
|
|
734aa72527 | ||
|
|
22ed51cf1f | ||
|
|
66745dd920 | ||
|
|
510b46636a | ||
|
|
156c113024 | ||
|
|
a83e288bff | ||
|
|
d8214a09f0 | ||
|
|
18cfca4307 | ||
|
|
54409fd61d | ||
|
|
55c0c1b499 | ||
|
|
45f21e84c7 | ||
|
|
0ff698db6f | ||
|
|
96bafcebbd | ||
|
|
21b2687e0f | ||
|
|
c464589a42 | ||
|
|
0dfb09fa69 | ||
|
|
939be0ec6b | ||
|
|
b6f21e8a94 | ||
|
|
f0a929a2ae | ||
|
|
cd793c11c9 | ||
|
|
e7262d4d65 | ||
|
|
0d98016511 | ||
|
|
b7d775a734 | ||
|
|
61d728f905 | ||
|
|
bc27becbbb | ||
|
|
dbae19e80d | ||
|
|
2f7e4b8fc0 | ||
|
|
cd7c586b15 | ||
|
|
7cb076c945 | ||
|
|
473bfbc73c | ||
|
|
0243cc2195 | ||
|
|
8bf74f0f7e | ||
|
|
c1b60b7af2 | ||
|
|
77aace4ae4 | ||
|
|
31adc25a1f | ||
|
|
016135d946 | ||
|
|
d9e74087e4 | ||
|
|
7a3ac9dbe6 | ||
|
|
b9ee841ea5 | ||
|
|
d4dad0f219 | ||
|
|
07ff3e45c4 | ||
|
|
4e601e95bc | ||
|
|
45ee184527 | ||
|
|
fdbefbac83 | ||
|
|
413ca989a1 | ||
|
|
939380f3d5 | ||
|
|
526617ff9b | ||
|
|
02a0ed4f74 | ||
|
|
8f00c97fae | ||
|
|
f6046bba7e | ||
|
|
177338282d | ||
|
|
c07d4020d0 | ||
|
|
996bf5a14d | ||
|
|
2d81d584a2 | ||
|
|
8768ee2ba2 | ||
|
|
daebbf61e7 | ||
|
|
ca5c36f65f | ||
|
|
1d3c957ff4 | ||
|
|
b9d09c9712 | ||
|
|
54641f4653 | ||
|
|
9d8332ad08 | ||
|
|
236f39e6c4 | ||
|
|
18b9556f3b | ||
|
|
340240473e | ||
|
|
c05b4090d8 | ||
|
|
6f2d0d8d0c | ||
|
|
73ee509439 | ||
|
|
8437ba4164 | ||
|
|
4381b71094 | ||
|
|
fe4a3043eb | ||
|
|
cdfd7d9849 | ||
|
|
3e01f18756 | ||
|
|
6032dbaa16 | ||
|
|
d5fc19e42c | ||
|
|
1493676217 | ||
|
|
a690aab42d | ||
|
|
7cb7981deb | ||
|
|
c0a0db3a70 | ||
|
|
312727d726 | ||
|
|
6485532d88 | ||
|
|
553f0ad61b | ||
|
|
15b388fc86 | ||
|
|
e6ddfab9e8 | ||
|
|
5cdcee2649 | ||
|
|
5be380ad14 | ||
|
|
9e4ddfcd87 | ||
|
|
07094d0dd1 | ||
|
|
821a307feb | ||
|
|
9984c68d37 | ||
|
|
357e4ddb0f | ||
|
|
4830b8ba6d | ||
|
|
78c2bcf6b6 | ||
|
|
2f51d525ff | ||
|
|
5e11db50ce | ||
|
|
92d30a498b | ||
|
|
eebe83e0c5 | ||
|
|
8920185baa | ||
|
|
c7f14fda89 | ||
|
|
f0f4d741ae | ||
|
|
8079f8f42a | ||
|
|
77bdbdbc74 | ||
|
|
713b7cbe6f | ||
|
|
51b15af09d | ||
|
|
c780a030b2 | ||
|
|
59739a2b48 | ||
|
|
725e2e4beb | ||
|
|
5dc25e0be3 | ||
|
|
cb4a13671d | ||
|
|
981021b2b6 | ||
|
|
b2c582dc5a | ||
|
|
7d864828b5 | ||
|
|
198b3e4ad4 | ||
|
|
fda5ef2931 | ||
|
|
fa6529db0e | ||
|
|
8c40cb7412 | ||
|
|
0a933af95f | ||
|
|
451f55f80d | ||
|
|
6699c4a8aa | ||
|
|
c6f0561b5b | ||
|
|
7cd0f505b2 | ||
|
|
8749f5077a | ||
|
|
a5ea8197ab | ||
|
|
19b91ae14f | ||
|
|
3f14d7fa75 | ||
|
|
3a06150d01 | ||
|
|
6a0d721f36 | ||
|
|
a542c21a42 | ||
|
|
a0fd52a627 | ||
|
|
f1db9a6c78 | ||
|
|
7bbd7a407f | ||
|
|
ccf515c3b1 | ||
|
|
44bed71ccd | ||
|
|
2fdb6e548e | ||
|
|
bbcb3b3b17 | ||
|
|
958dd44fee | ||
|
|
380584b86b | ||
|
|
c45ed6ba52 | ||
|
|
a44804fd59 | ||
|
|
5c35f32e22 | ||
|
|
4f6ec3ed4d | ||
|
|
3f89eff70a | ||
|
|
9814a67ee6 | ||
|
|
d034aa00e5 | ||
|
|
1290eb2b06 | ||
|
|
70882918e5 | ||
|
|
a7df68a59a | ||
|
|
b9d0d8c2d9 | ||
|
|
0a1efb73dd | ||
|
|
127cfccccc | ||
|
|
f3b1209207 | ||
|
|
5d77e9cf46 | ||
|
|
174e59e692 | ||
|
|
2de4eda16d | ||
|
|
fd1b676e28 | ||
|
|
738bbe1579 | ||
|
|
022b914c66 | ||
|
|
b49b95dc7a | ||
|
|
6dc5f1cfa6 | ||
|
|
539a2dc639 | ||
|
|
ad9b67d599 | ||
|
|
ba8e872b59 | ||
|
|
8ea12de732 | ||
|
|
8a82f789d1 | ||
|
|
ffb93dc55d | ||
|
|
028b0eb015 | ||
|
|
20d50ef9f1 | ||
|
|
ded40d071e | ||
|
|
cfc3c94cff | ||
|
|
d1e2cc929d | ||
|
|
ccb1b1ebe5 | ||
|
|
f1edb70fbd |
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"version": 1,
|
||||
"hooks": {
|
||||
"beforeShellExecution": [
|
||||
{
|
||||
"command": ".cursor/hooks/guard-git.sh",
|
||||
"matcher": "^git ",
|
||||
"timeout": 10,
|
||||
"failClosed": true
|
||||
},
|
||||
{
|
||||
"command": ".cursor/hooks/guard-pi-shell.sh",
|
||||
"matcher": "pi_subagents\\.py|pkill",
|
||||
"timeout": 10,
|
||||
"failClosed": true
|
||||
}
|
||||
],
|
||||
"beforeMCPExecution": [
|
||||
{
|
||||
"command": ".cursor/hooks/guard-pi-dispatch.sh",
|
||||
"matcher": "pi-subagents|pi_subagent_",
|
||||
"timeout": 10,
|
||||
"failClosed": true
|
||||
}
|
||||
],
|
||||
"postToolUse": [
|
||||
{
|
||||
"command": ".cursor/hooks/pi-receipt-context.sh",
|
||||
"matcher": "MCP: pi-subagents|pi_subagent_",
|
||||
"timeout": 10,
|
||||
"failClosed": false
|
||||
}
|
||||
],
|
||||
"sessionStart": [
|
||||
{
|
||||
"command": ".cursor/hooks/audit-session.sh",
|
||||
"timeout": 20,
|
||||
"failClosed": false
|
||||
}
|
||||
],
|
||||
"stop": [
|
||||
{
|
||||
"command": ".cursor/hooks/audit-session.sh",
|
||||
"timeout": 10,
|
||||
"failClosed": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Shared helpers for project Cursor hooks (advisory gates + audit/probe)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
from typing import Any
|
||||
|
||||
KNOWN_ROLES = frozenset(
|
||||
{
|
||||
"research",
|
||||
"planning",
|
||||
"requirements_review",
|
||||
"plan_review",
|
||||
"code_review",
|
||||
"diagnosis",
|
||||
"test_run",
|
||||
"acceptance_check",
|
||||
"stage_notes",
|
||||
"report",
|
||||
"auxiliary",
|
||||
}
|
||||
)
|
||||
TEST_ROLES = frozenset({"test_run", "acceptance_check"})
|
||||
FULL_SHA = re.compile(r"^[0-9a-fA-F]{40}$")
|
||||
REQUEST_ID = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$")
|
||||
|
||||
|
||||
def repo_root() -> Path:
|
||||
env = os.environ.get("CURSOR_PROJECT_DIR") or os.environ.get("CURSOR_WORKSPACE_ROOT")
|
||||
if env:
|
||||
return Path(env).resolve()
|
||||
# hooks run with cwd = project root
|
||||
return Path.cwd().resolve()
|
||||
|
||||
|
||||
def audit_path() -> Path:
|
||||
return repo_root() / ".cursor" / "hook-audit.jsonl"
|
||||
|
||||
|
||||
def probe_path() -> Path:
|
||||
return repo_root() / ".cursor" / "hook-probe.jsonl"
|
||||
|
||||
|
||||
def inventory_dir() -> Path:
|
||||
return repo_root() / ".cursor" / "hook-audit"
|
||||
|
||||
|
||||
def append_jsonl(path: Path, record: dict[str, Any]) -> None:
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
record = dict(record)
|
||||
record.setdefault("ts", datetime.now(timezone.utc).isoformat())
|
||||
with path.open("a", encoding="utf-8") as fh:
|
||||
fh.write(json.dumps(record, ensure_ascii=False) + "\n")
|
||||
|
||||
|
||||
def read_stdin() -> str:
|
||||
return sys.stdin.read()
|
||||
|
||||
|
||||
def maybe_probe(raw: str, hook: str) -> None:
|
||||
if os.environ.get("CURSOR_HOOKS_PROBE", "").strip() not in ("1", "true", "TRUE", "yes"):
|
||||
return
|
||||
append_jsonl(
|
||||
probe_path(),
|
||||
{"hook": hook, "raw": raw[:65536], "raw_len": len(raw)},
|
||||
)
|
||||
|
||||
|
||||
def parse_json_loose(raw: str) -> dict[str, Any] | None:
|
||||
raw = (raw or "").strip()
|
||||
if not raw:
|
||||
return None
|
||||
try:
|
||||
data = json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
return data if isinstance(data, dict) else None
|
||||
|
||||
|
||||
def first_key(data: dict[str, Any], *names: str) -> Any:
|
||||
for name in names:
|
||||
if name in data and data[name] is not None:
|
||||
return data[name]
|
||||
return None
|
||||
|
||||
|
||||
def normalize_tool_name(name: str | None) -> str | None:
|
||||
"""Strip Cursor MCP prefixes such as 'MCP:' / 'MCP: pi-subagents/'."""
|
||||
if name is None:
|
||||
return None
|
||||
n = str(name).strip()
|
||||
# Observed IDE postToolUse: tool_name == "MCP:pi_subagent_roles"
|
||||
if n.upper().startswith("MCP:"):
|
||||
n = n[4:].lstrip()
|
||||
# Rare: "MCP: pi-subagents/pi_subagent_run"
|
||||
if "/" in n and n.rsplit("/", 1)[-1].startswith("pi_subagent_"):
|
||||
n = n.rsplit("/", 1)[-1]
|
||||
return n or None
|
||||
|
||||
|
||||
def tool_name(data: dict[str, Any]) -> str | None:
|
||||
v = first_key(data, "tool_name", "mcp_tool_name", "name", "toolName")
|
||||
return normalize_tool_name(str(v) if v is not None else None)
|
||||
|
||||
|
||||
def mcp_server(data: dict[str, Any]) -> str | None:
|
||||
v = first_key(data, "mcp_server_name", "server", "mcpServer", "server_name")
|
||||
return str(v) if v is not None else None
|
||||
|
||||
|
||||
def tool_input(data: dict[str, Any]) -> dict[str, Any] | None:
|
||||
v = first_key(data, "tool_input", "arguments", "input", "toolInput", "params")
|
||||
if isinstance(v, dict):
|
||||
return v
|
||||
if isinstance(v, str):
|
||||
try:
|
||||
parsed = json.loads(v)
|
||||
return parsed if isinstance(parsed, dict) else None
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
return None
|
||||
|
||||
|
||||
def shell_command(data: dict[str, Any]) -> str:
|
||||
v = first_key(data, "command", "shell_command", "cmd")
|
||||
return str(v) if v is not None else ""
|
||||
|
||||
|
||||
def emit(obj: dict[str, Any]) -> None:
|
||||
sys.stdout.write(json.dumps(obj, ensure_ascii=False))
|
||||
sys.stdout.flush()
|
||||
|
||||
|
||||
def allow() -> None:
|
||||
emit({"permission": "allow"})
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
def ask(user_message: str, agent_message: str) -> None:
|
||||
emit(
|
||||
{
|
||||
"permission": "ask",
|
||||
"user_message": user_message,
|
||||
"agent_message": agent_message,
|
||||
}
|
||||
)
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
def additional_context(text: str) -> None:
|
||||
emit({"additional_context": text})
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
def audit(hook: str, code: str, **extra: Any) -> None:
|
||||
rec = {"hook": hook, "code": code}
|
||||
rec.update(extra)
|
||||
try:
|
||||
append_jsonl(audit_path(), rec)
|
||||
except OSError:
|
||||
pass
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
exec python3 -B "$DIR/audit_session.py"
|
||||
@@ -0,0 +1,101 @@
|
||||
#!/usr/bin/env python3
|
||||
"""sessionStart / stop: audit + optional fail-open inventory (no context injection)."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from datetime import datetime, timezone
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
import _lib as lib # noqa: E402
|
||||
|
||||
HOOK = "audit-session"
|
||||
INVENTORY_TIMEOUT = 15
|
||||
|
||||
|
||||
def _run_inventory(root: Path) -> dict:
|
||||
out: dict = {"cleanup_report": None, "docs_drift": None, "errors": []}
|
||||
if os.environ.get("CURSOR_HOOKS_NO_INVENTORY", "").strip() in ("1", "true", "TRUE", "yes"):
|
||||
out["skipped"] = "CURSOR_HOOKS_NO_INVENTORY"
|
||||
return out
|
||||
agentctl = root / "scripts" / "agentctl.py"
|
||||
if not agentctl.is_file():
|
||||
out["errors"].append("agentctl.py missing")
|
||||
return out
|
||||
for label, args in (
|
||||
("cleanup_report", ["cleanup", "report"]),
|
||||
("docs_drift", ["docs", "drift"]),
|
||||
):
|
||||
try:
|
||||
r = subprocess.run(
|
||||
["python3", "-B", str(agentctl), *args],
|
||||
cwd=str(root),
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=INVENTORY_TIMEOUT,
|
||||
check=False,
|
||||
)
|
||||
payload = None
|
||||
for stream in (r.stdout, r.stderr):
|
||||
for line in (stream or "").splitlines():
|
||||
line = line.strip()
|
||||
if line.startswith("{"):
|
||||
try:
|
||||
payload = json.loads(line)
|
||||
break
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
if payload is not None:
|
||||
break
|
||||
out[label] = {
|
||||
"exit_code": r.returncode,
|
||||
"payload": payload,
|
||||
"stdout_tail": (r.stdout or "")[-2000:],
|
||||
"stderr_tail": (r.stderr or "")[-1000:],
|
||||
}
|
||||
except subprocess.TimeoutExpired:
|
||||
out["errors"].append(f"{label}: timeout>{INVENTORY_TIMEOUT}s")
|
||||
except OSError as exc:
|
||||
out["errors"].append(f"{label}: {exc}")
|
||||
return out
|
||||
|
||||
|
||||
def main() -> None:
|
||||
raw = lib.read_stdin()
|
||||
lib.maybe_probe(raw, HOOK)
|
||||
data = lib.parse_json_loose(raw) or {}
|
||||
event = str(
|
||||
lib.first_key(data, "hook_event_name", "event", "event_name", "type") or "unknown"
|
||||
)
|
||||
root = lib.repo_root()
|
||||
if "start" in event.lower() or event == "unknown":
|
||||
inv = _run_inventory(root)
|
||||
inv_path = None
|
||||
try:
|
||||
inv_dir = lib.inventory_dir()
|
||||
inv_dir.mkdir(parents=True, exist_ok=True)
|
||||
ts = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%SZ")
|
||||
path = inv_dir / f"inventory-{ts}.json"
|
||||
path.write_text(json.dumps(inv, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
||||
inv_path = str(path)
|
||||
except OSError:
|
||||
pass
|
||||
lib.audit(
|
||||
HOOK,
|
||||
"SESSION_AUDIT",
|
||||
event=event,
|
||||
inventory_path=inv_path,
|
||||
inventory_errors=inv.get("errors"),
|
||||
)
|
||||
else:
|
||||
lib.audit(HOOK, "SESSION_AUDIT", event=event)
|
||||
|
||||
lib.emit({})
|
||||
raise SystemExit(0)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
# Fail-closed red-line gate for destructive / unauthorized git. Does not replace agentctl leases.
|
||||
set -euo pipefail
|
||||
input=$(cat)
|
||||
command=$(printf '%s' "$input" | python3 -c 'import json,sys; print(json.load(sys.stdin).get("command") or "")')
|
||||
|
||||
ask() {
|
||||
local user_msg="$1"
|
||||
local agent_msg="$2"
|
||||
python3 -c 'import json,sys; print(json.dumps({"permission":"ask","user_message":sys.argv[1],"agent_message":sys.argv[2]}))' "$user_msg" "$agent_msg"
|
||||
exit 0
|
||||
}
|
||||
|
||||
allow() {
|
||||
echo '{"permission":"allow"}'
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Normalize whitespace for matching
|
||||
cmd=$(printf '%s' "$command" | tr '\n' ' ')
|
||||
|
||||
# Unauthorized push (user must confirm)
|
||||
if printf '%s' "$cmd" | grep -Eq '(^|[[:space:]])git([[:space:]]+-[^[:space:]]+)*[[:space:]]+push([[:space:]]|$)'; then
|
||||
ask "git push 需要显式用户授权(AGENTS remote_sync)。请确认后再继续。" \
|
||||
"Hook blocked git push pending user authorization."
|
||||
fi
|
||||
|
||||
# Destructive / force operations
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+.*(--force|-f)([[:space:]]|$)' \
|
||||
|| printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+push[[:space:]].*\+'; then
|
||||
ask "检测到 git --force / 强推。破坏性操作须用户明确授权。" \
|
||||
"Hook requires confirmation for force git operation."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+reset[[:space:]]+.*--hard'; then
|
||||
ask "git reset --hard 会丢弃工作区。须用户明确授权。" \
|
||||
"Hook requires confirmation for git reset --hard."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+clean[[:space:]]+.*-[a-zA-Z]*f'; then
|
||||
ask "git clean -f 会删除未跟踪文件。须用户明确授权。" \
|
||||
"Hook requires confirmation for git clean -f."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+branch[[:space:]]+(-D|--delete[[:space:]]+--force)'; then
|
||||
ask "强制删分支 (-D) 须用户明确授权;优先 git branch -d。" \
|
||||
"Hook requires confirmation for git branch -D."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+worktree[[:space:]]+remove[[:space:]]+.*--force'; then
|
||||
ask "git worktree remove --force 被 AGENTS 禁止升级。须用户明确授权。" \
|
||||
"Hook requires confirmation for forced worktree remove."
|
||||
fi
|
||||
|
||||
if printf '%s' "$cmd" | grep -Eq 'git[[:space:]]+checkout[[:space:]]+--\.($|[[:space:]])'; then
|
||||
ask "git checkout -- . 会丢弃全部本地修改。须用户明确授权。" \
|
||||
"Hook requires confirmation for discarding all local changes."
|
||||
fi
|
||||
|
||||
allow
|
||||
Executable
+5
@@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env bash
|
||||
# Thin wrapper: preserve stdin for Cursor hook JSON (do not use heredoc).
|
||||
set -euo pipefail
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
exec python3 -B "$DIR/guard_pi_dispatch.py"
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
exec python3 -B "$DIR/guard_pi_shell.py"
|
||||
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Advisory beforeMCPExecution gate for pi-subagents MCP tools."""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
import _lib as lib # noqa: E402
|
||||
|
||||
HOOK = "guard-pi-dispatch"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
raw = lib.read_stdin()
|
||||
lib.maybe_probe(raw, HOOK)
|
||||
data = lib.parse_json_loose(raw)
|
||||
if data is None:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
|
||||
lib.allow()
|
||||
|
||||
name = lib.tool_name(data)
|
||||
server = lib.mcp_server(data)
|
||||
if not name:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_tool_name", keys=sorted(data.keys())[:40])
|
||||
lib.allow()
|
||||
|
||||
if server and "pi-subagents" not in server and not name.startswith("pi_subagent_"):
|
||||
if not name.startswith("pi_subagent_"):
|
||||
lib.allow()
|
||||
|
||||
if name in ("pi_subagent_roles", "pi_subagent_result"):
|
||||
lib.allow()
|
||||
|
||||
if name != "pi_subagent_run":
|
||||
if name.startswith("pi_subagent_"):
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="unknown_pi_tool", tool=name)
|
||||
lib.allow()
|
||||
|
||||
args = lib.tool_input(data) or {}
|
||||
req = args.get("request") if isinstance(args.get("request"), dict) else args
|
||||
if not isinstance(req, dict):
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_request")
|
||||
lib.ask(
|
||||
"pi_subagent_run 缺少可识别的 request 对象。请核对 MCP 参数后再继续。",
|
||||
"Hook: unrecognized request shape for pi_subagent_run.",
|
||||
)
|
||||
|
||||
role = req.get("role_id")
|
||||
request_id = req.get("request_id")
|
||||
goal = req.get("goal")
|
||||
auth = req.get("authorization_ref")
|
||||
source_sha = req.get("source_sha")
|
||||
input_files = req.get("input_files")
|
||||
timeout = req.get("timeout_seconds")
|
||||
|
||||
problems: list[str] = []
|
||||
|
||||
if not role or not isinstance(role, str):
|
||||
problems.append("role_id 缺失")
|
||||
elif role not in lib.KNOWN_ROLES:
|
||||
problems.append(f"role_id={role!r} 不在已知角色表")
|
||||
|
||||
if not request_id or not isinstance(request_id, str) or not lib.REQUEST_ID.match(request_id):
|
||||
problems.append("request_id 非法(需字母数字开头,长度≤128)")
|
||||
|
||||
if not goal or not isinstance(goal, str) or not goal.strip():
|
||||
problems.append("goal 为空")
|
||||
|
||||
if not auth or not isinstance(auth, str) or not auth.strip():
|
||||
problems.append("authorization_ref 为空")
|
||||
|
||||
if not isinstance(source_sha, str) or not lib.FULL_SHA.match(source_sha):
|
||||
problems.append("source_sha 必须是完整 40-hex 提交(禁止 HEAD/分支名/短 hash)")
|
||||
|
||||
if not isinstance(input_files, list):
|
||||
problems.append("input_files 必须是数组")
|
||||
|
||||
if not isinstance(timeout, int) or isinstance(timeout, bool) or timeout <= 0:
|
||||
if isinstance(timeout, float) and timeout.is_integer() and timeout > 0:
|
||||
pass
|
||||
else:
|
||||
problems.append("timeout_seconds 必须是正整数")
|
||||
|
||||
if isinstance(role, str) and role in lib.TEST_ROLES:
|
||||
cmds = req.get("approved_commands")
|
||||
digest = req.get("plan_digest")
|
||||
if not isinstance(cmds, list) or not cmds:
|
||||
problems.append("test 角色需要 approved_commands(argv 数组的数组)")
|
||||
elif any(not isinstance(c, list) or not all(isinstance(x, str) for x in c) for c in cmds):
|
||||
problems.append("approved_commands 形状错误(应为字符串数组的数组)")
|
||||
if not isinstance(digest, str) or len(digest) != 64 or any(
|
||||
c not in "0123456789abcdefABCDEF" for c in digest
|
||||
):
|
||||
problems.append("plan_digest 必须是 64-hex SHA-256")
|
||||
|
||||
if "model_override" in req and req.get("model_override") is not None:
|
||||
problems.append("出现 model_override(禁止静默换模型;请用任务 override)")
|
||||
|
||||
if problems:
|
||||
detail = ";".join(problems)
|
||||
lib.audit(HOOK, "SHAPE_ASK", tool=name, problems=problems, role=role, request_id=request_id)
|
||||
lib.ask(
|
||||
f"pi_subagent_run 形状检查未通过:{detail}。执行器仍会硬校验;确认后继续或修正参数。",
|
||||
f"Hook advisory: {detail}",
|
||||
)
|
||||
|
||||
lib.audit(HOOK, "ALLOW", tool=name, role=role, request_id=request_id)
|
||||
lib.allow()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Advisory beforeShellExecution: bare pi_subagents.py run / broad pkill."""
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
import _lib as lib # noqa: E402
|
||||
|
||||
HOOK = "guard-pi-shell"
|
||||
|
||||
|
||||
def main() -> None:
|
||||
raw = lib.read_stdin()
|
||||
lib.maybe_probe(raw, HOOK)
|
||||
data = lib.parse_json_loose(raw)
|
||||
if data is None:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
|
||||
lib.allow()
|
||||
|
||||
cmd = lib.shell_command(data)
|
||||
if not cmd:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="missing_command", keys=sorted(data.keys())[:40])
|
||||
lib.allow()
|
||||
|
||||
compact = re.sub(r"\s+", " ", cmd).strip()
|
||||
|
||||
if re.search(r"(^|[;&|]\s*)pkill(\s|$)", compact) and re.search(r"\s-f(\s|$)", compact):
|
||||
lib.audit(HOOK, "PKILL_ASK", command=compact[:500])
|
||||
lib.ask(
|
||||
"检测到 pkill -f(广谱杀进程)。AGENTS/PI 规则禁止广谱杀;请确认范围后再继续。",
|
||||
"Hook requires confirmation for pkill -f.",
|
||||
)
|
||||
|
||||
if re.search(r"pi_subagents\.py(\s|$)", compact) and re.search(r"(^|\s)run(\s|$)", compact):
|
||||
has_lease = (
|
||||
re.search(r"agentctl(\.py)?\s+with\b", compact) is not None
|
||||
and re.search(r"--resource\s+path:", compact) is not None
|
||||
)
|
||||
if re.search(r"pi_subagents\.py\s+(roles|result|status|config)\b", compact):
|
||||
lib.allow()
|
||||
if not has_lease:
|
||||
lib.audit(HOOK, "BARE_RUN_ASK", command=compact[:500])
|
||||
lib.ask(
|
||||
"裸调 pi_subagents.py run 缺少 agentctl with --resource path:… 租约。"
|
||||
"报告路径须在 path:.doc/test-reports/assets/pi-subagents/<task>/<request> 租约内。",
|
||||
"Hook: bare PI run without lease resource.",
|
||||
)
|
||||
|
||||
lib.allow()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Executable
+4
@@ -0,0 +1,4 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
exec python3 -B "$DIR/pi_receipt_context.py"
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env python3
|
||||
"""postToolUse: inject receipt-check reminders after pi-subagents tools."""
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent))
|
||||
import _lib as lib # noqa: E402
|
||||
|
||||
HOOK = "pi-receipt-context"
|
||||
|
||||
REMINDER = """[PI subagent receipt checklist]
|
||||
- 核对 report/receipt 路径:.doc/test-reports/assets/pi-subagents/<task_id>/<request_id>/
|
||||
- 记录 config_revision / config_sha256 / configured vs actual_model(不可观察填 unknown)
|
||||
- run_status=succeeded 不等于阶段 PASS;review_state 仍可为 pending
|
||||
- 测试 pass 只来自批准命令证据(approved_commands),不能用模型叙事冒充
|
||||
- 推进门禁前用 subagent-stage-record skill 写回传与阶段收据
|
||||
"""
|
||||
|
||||
|
||||
def main() -> None:
|
||||
raw = lib.read_stdin()
|
||||
lib.maybe_probe(raw, HOOK)
|
||||
data = lib.parse_json_loose(raw)
|
||||
if data is None:
|
||||
lib.audit(HOOK, "UNRECOGNIZED_INPUT", reason="non_json_or_empty")
|
||||
lib.emit({})
|
||||
raise SystemExit(0)
|
||||
|
||||
name = lib.tool_name(data) or ""
|
||||
server = lib.mcp_server(data) or ""
|
||||
blob = raw
|
||||
is_pi = (
|
||||
name.startswith("pi_subagent_")
|
||||
or "pi-subagents" in server
|
||||
or "pi_subagent_" in blob
|
||||
)
|
||||
if not is_pi:
|
||||
lib.emit({})
|
||||
raise SystemExit(0)
|
||||
|
||||
lib.audit(HOOK, "CONTEXT_INJECT", tool=name or "unknown")
|
||||
lib.additional_context(REMINDER)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"mcpServers": {
|
||||
"agentctl": {
|
||||
"type": "stdio",
|
||||
"command": "node",
|
||||
"args": ["scripts/mcp/agentctl-mcp.mjs"]
|
||||
},
|
||||
"jev": {
|
||||
"type": "stdio",
|
||||
"command": "node",
|
||||
"args": ["scripts/mcp/jev-mcp.mjs"]
|
||||
},
|
||||
"codegraph": {
|
||||
"type": "stdio",
|
||||
"command": "codegraph",
|
||||
"args": ["serve", "--mcp", "--path", "${workspaceFolder}"]
|
||||
},
|
||||
"pi-subagents": {
|
||||
"type": "stdio",
|
||||
"command": "node",
|
||||
"args": ["scripts/mcp/pi-subagents-mcp.mjs"]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
description: Cursor 对话自动生成的会话名称使用简体中文
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# 会话名称(中文)
|
||||
|
||||
Cursor 为本对话自动生成或建议的**会话名称 / 聊天标题**必须使用**简体中文**。
|
||||
|
||||
## 要求
|
||||
|
||||
- 用简短中文概括当前任务主题(约 6–16 字)
|
||||
- 优先动词/对象:如「创建会话中文命名规则」「修复登录超时」
|
||||
- 禁止默认英文标题(专有名词、命令、路径可保留原文,整体仍以中文为主)
|
||||
|
||||
## 示例
|
||||
|
||||
| 场景 | 可用标题 |
|
||||
|---|---|
|
||||
| 新建 Cursor 规则 | 创建会话中文命名规则 |
|
||||
| 排查 hook | 排查 pi-dispatch hook |
|
||||
| 合入 feature | 合入治理目录库变更 |
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
description: Cursor hooks are client-side advisories only. Remote authority is Gitea native protection (2026-09-29); agentctl gates are retired for coding flow.
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# Cursor hooks(客户端门禁)
|
||||
|
||||
配置:`.cursor/hooks.json`;脚本:`.cursor/hooks/`。规范登记修订 `cursor-governance-2026-09-24-r1`。
|
||||
|
||||
## 分层
|
||||
|
||||
| 层 | 能力 | 说明 |
|
||||
|---|---|---|
|
||||
| Gitea 服务端 | **enforced** | 受保护分支、必需 CI、非作者批准(2026-09-29 起) |
|
||||
| 本地 agentctl | 已退役(仅维护场景可选) | pre-commit/租约等本地硬拒绝已停用 |
|
||||
| hook 脚本行为 | **enforced**(有单元回归) | stdin→stdout 契约可测 |
|
||||
| hook ↔ Cursor 接线 | **advisory / manual** | 官方事件字段未完全文档化;待 probe 采样后收紧 |
|
||||
|
||||
命中策略:与 `guard-git.sh` 一致,一律 `permission: ask`(不静默 deny)。
|
||||
|
||||
## 事件与脚本
|
||||
|
||||
- `beforeShellExecution`:`guard-git.sh`(破坏性 git);`guard-pi-shell.sh`(裸调 `pi_subagents.py run`、`pkill -f`)
|
||||
- `beforeMCPExecution`:`guard-pi-dispatch.sh`(`pi_subagent_run` 形状)
|
||||
- `postToolUse`:`pi-receipt-context.sh`(注入收据核对提醒)
|
||||
- `sessionStart` / `stop`:`audit-session.sh`(审计 + 可选只读盘点;**不注入上下文**)
|
||||
|
||||
IDE 实测(2026-09-24):`postToolUse` 的 `tool_name` 形如 `MCP:pi_subagent_roles`;hooks 须剥 `MCP:` 前缀后再匹配角色工具名。
|
||||
|
||||
## 审计与 probe
|
||||
|
||||
- 审计:`.cursor/hook-audit.jsonl`(gitignore;勿提交)
|
||||
- 盘点:`.cursor/hook-audit/inventory-*.json`
|
||||
- 采样:`CURSOR_HOOKS_PROBE=1` → `.cursor/hook-probe.jsonl`
|
||||
- 关闭盘点:`CURSOR_HOOKS_NO_INVENTORY=1`
|
||||
|
||||
异形/未知字段:**fail-open + 审计 `UNRECOGNIZED_INPUT`**,不因契约未知卡死会话。
|
||||
|
||||
## 红线
|
||||
|
||||
- 不把 hook 复刻成第二套执行器门禁
|
||||
- 脚本存在 ≠ Cursor 已加载;改 hooks 后检查 Hooks 设置页或通道
|
||||
- 审计日志不得放进被 git 跟踪的 `.cursor/hooks/` 目录
|
||||
@@ -0,0 +1,24 @@
|
||||
---
|
||||
description: Route PI analysis/review/test subagent work through scripts/pi_subagents.py (not Cursor native agents).
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# PI subagents(工程工具)
|
||||
|
||||
本机 PI 子任务走 `scripts/pi_subagents.py` + 模型配置 `.doc/ops/2026-09-24-subagent-model-config.md`。可执行步骤见 skill `pi-subagent-dispatch`;阶段记录见 `subagent-stage-record`。
|
||||
|
||||
## 自动派发(主 Agent)
|
||||
|
||||
1. **预览配置**:`pi_subagent_roles` / CLI `roles`(不调模型)。
|
||||
2. **按阶段选角色**:research → planning → reviews → diagnosis → test_run / acceptance_check → report;实施/修复仍由 Cursor Auto。
|
||||
3. **派发 `run`**:携带 task_id、role_id、唯一 request_id、goal、authorization_ref、冻结 source_sha、input_files、timeout;test 角色另附 approved_commands + plan_digest。
|
||||
4. **租约**:报告路径 `path:.doc/test-reports/assets/pi-subagents/<task>/<request>`;裸调拒绝。
|
||||
5. **取回**:`pi_subagent_result` / CLI `result`;`run_status` 与 `verdict`/`review_state` 分离——模型成功仅 `pending`,测试 pass 仅来自批准命令证据。
|
||||
6. **门禁**:审查/测试结论须带回报告路径与 receipt 字段;不得用模型叙事冒充 PASS。
|
||||
|
||||
## 边界
|
||||
|
||||
- **Cursor Auto**:唯一代码实施车道;本规则不把 implementation 派给 PI。
|
||||
- **禁止**:自动换模型、M3 关键角色、伪造 lease、递归把本修复任务再派给 PI worker、`pkill -f` 广谱杀进程。
|
||||
- **MCP**:`.cursor/mcp.json` → `pi-subagents`(roles/run/result);executor 来自 MCP 安装根。
|
||||
- **Hook(advisory)**:`.cursor/hooks/guard-pi-dispatch.sh` / `guard-pi-shell.sh` 可在形状错误时 `ask`;**硬拒绝以执行器为准**,见规则 `cursor-hooks`。
|
||||
@@ -1,6 +1,63 @@
|
||||
---
|
||||
description: 按变更范围选择测试及真实证据要求
|
||||
description: Cursor-side test report path/naming conventions; validation scope comes from the validation contract.
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
测试范围、精确产品 PI 入口、环境模型证据和报告格式统一见 [验证契约](../../.doc/ops/2026-09-21-validation-contract.md)。按实际变更选择适用行;报告大小不扩大测试范围。
|
||||
# 测试报告规范准则 (Test Reports Standard)
|
||||
|
||||
本仓库严格遵循标准化、可追溯的质量测试管理体系。**验证范围、套件选择与模型证据的唯一来源**为 [验证契约](../../.doc/ops/2026-09-21-validation-contract.md);本规则只约定 Cursor 侧的报告路径、命名与结构提醒,不另设第二套测试门禁。
|
||||
|
||||
**范围判定**:纯工程规范/文档变更按 [PROJECT.md 验证入口](../../PROJECT.md#验证入口) 与 [worktree 工作规范](../../.doc/ops/2026-09-21-agent-worktree-workflow.md) 检查链接、规则一致性及 Git 差异;不适用产品 PI 全链路。报告注明 NOT REQUIRED 及依据,不能记成产品测试 PASS。运行模板、提示词和业务变更不属于此例外——按验证契约选层级。
|
||||
|
||||
## 一、 测试报告归档路径规范
|
||||
|
||||
- **统一目录**:所有测试报告必须统一存放于 `.doc/test-reports/` 目录下。
|
||||
- **命名规范**:遵循 `YYYY-MM-DD-<模块/功能/版本>-test-report.md` 命名格式。
|
||||
- 例如:`.doc/test-reports/2026-09-07-three-branch-intent-framework-test-report.md`
|
||||
- **证据附件**:运行产物(json/jsonl、workspace 快照、截图)放 `.doc/test-reports/assets/<report-slug>/`,**不得**与 `*-test-report.md` 混放在同一层级目录。
|
||||
|
||||
## 二、 测试报告固定结构模板
|
||||
|
||||
每份独立测试报告应包含以下核心板块(小型文档/脚本任务可在任务主文档设验证节,无需机械拆报告):
|
||||
|
||||
```markdown
|
||||
# [功能/模块名称] 测试报告
|
||||
|
||||
## 一、 测试背景 (Background)
|
||||
- 简述被测功能/特性的产生背景、业务痛点或上一轮测试中发现的缺陷与瓶颈。
|
||||
|
||||
## 二、 测试目标 (Test Objectives)
|
||||
- 列举本次测试需要验证的核心功能点、质量指标。
|
||||
|
||||
## 三、 测试方案与环境 (Test Plan & Environment)
|
||||
- 测试环境(OS、工具版本、目标环境批准配置);
|
||||
- 测试层级分层(按验证契约矩阵选行);
|
||||
- 核心测试用例矩阵设计。
|
||||
|
||||
## 四、 预期结果 (Expected Results)
|
||||
- 明确给出各用例输入下的理论判定。
|
||||
|
||||
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
|
||||
- 必须包含针对每一个典型测试用例的真实记录:
|
||||
- **测试输入 (Input)**
|
||||
- **实际输出 (Actual Output)**:贴出真实的终端/日志输出文本(可脱敏)
|
||||
- **评价判定 (Evaluation / Verdict)**:PASS / FAIL / SKIP / 未运行
|
||||
- **性能与耗时 (Duration & Latency)**
|
||||
|
||||
## 六、 自动化测试套件汇总 (Test Suite Execution)
|
||||
- 只列本次适用并**实际运行**的检查与通过率;不无条件要求全量 `go test`。
|
||||
- 工程工具改动优先 `python3 -B -m unittest discover -s scripts/tests -p 'test_*.py' -v`(见验证契约「工程工具验收补充」)。
|
||||
|
||||
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
|
||||
- 总结测试是否达到授权交付终点,提出后续演进或强化点。
|
||||
```
|
||||
|
||||
## 三、 执行要求与真实 Agent 交付铁律
|
||||
|
||||
1. **真实 Agent 交付铁律(红线)**:
|
||||
- **开发实现阶段**:可以快速使用 stub 验证状态机、协议分流、数据落盘与逻辑契约,加速反馈;
|
||||
- **交付前验收与测试报告生成**:涉及产品 Agent/工作流时,必须按验证契约「产品 PI 基线」在获授权环境用真实产品 PI Agent Runner 全链路实测;模型以目标环境批准配置为准,不得在本规则中硬编码模型名;
|
||||
- **严禁**使用 stub、SKIP、未运行输出作为最终交付报告的验收数据。
|
||||
2. **严禁散落存放**:测试报告统一归档至 `.doc/test-reports/`,禁止散落在根目录或临时沙箱中。
|
||||
3. **真实控制台取样**:测试报告中的输入、输出、耗时与判定必须取自实际环境运行的真实控制台输出与日志。
|
||||
4. **Git 规范管理**:测试报告伴随对应阶段的 `docs(test)` 或 `test(...)` 规范提交入库。
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
---
|
||||
name: agentctl-integrate-closeout
|
||||
description: Validate a merge candidate, enqueue for daemon ff-only integrate, and close out five-state. Use when ready to land a task on local dev.
|
||||
---
|
||||
|
||||
# agentctl 集成与收口
|
||||
|
||||
权威:[操作规范](../../../.doc/ops/2026-09-21-agent-worktree-workflow.md)、[验证契约](../../../.doc/ops/2026-09-21-validation-contract.md)。常驻 daemon 已装载时走 **enqueue**,勿手动 `integrate`(除非 daemon 停)。
|
||||
|
||||
## 候选
|
||||
|
||||
优先一层封装(创建 integrate worktree、`task register`、`--no-ff` merge;**不** validate/enqueue):
|
||||
|
||||
```bash
|
||||
D=$(git -C /path/to/Agent-System rev-parse HEAD) # 冻结 expected-dev
|
||||
python3 scripts/agentctl.py integrate prepare \
|
||||
--task <feature-task-id> --expected-dev "$D" \
|
||||
[--integrate-id integrate-<task>-YYYY-MM-DD]
|
||||
# 进入返回的 worktree 继续 validate → enqueue
|
||||
cd .worktrees/integrate-<task>-YYYY-MM-DD # 或 emit 中的 worktree
|
||||
```
|
||||
|
||||
第一父必须等于 `$D`。手工 `worktree add` + `with` + `merge --no-ff` 仍可用。
|
||||
|
||||
## validate → enqueue(daemon ff)
|
||||
|
||||
```bash
|
||||
python3 ../../scripts/agentctl.py validate --task "$ID" -- <验收命令>
|
||||
python3 ../../scripts/agentctl.py queue enqueue \
|
||||
--task "$ID" --expected-dev "$D" --head "$(git rev-parse HEAD)"
|
||||
# 在任务 worktree 内 enqueue;数秒内 daemon 合入
|
||||
python3 ../../scripts/agentctl.py queue list
|
||||
python3 ../../scripts/agentctl.py daemon status
|
||||
```
|
||||
|
||||
验收按验证契约选行;治理脚本用 `unittest discover`。
|
||||
|
||||
## 五态收口
|
||||
|
||||
| 字段 | 典型值 |
|
||||
|---|---|
|
||||
| review_state | accepted |
|
||||
| integration_state | merged_local_dev |
|
||||
| deployment | not_required 或 loaded_local_launchd |
|
||||
| cleanup | pending(独立维护者;禁止 `--force`) |
|
||||
| remote_sync | not_requested |
|
||||
|
||||
CURRENT 行 → `done`(`docs apply`);`task close --status done`。
|
||||
|
||||
## 清理前
|
||||
|
||||
确认 tip 为 local_dev 祖先、证据已持久化、无 tracked/untracked 遗留、无进程占用。唯一日志/对话归档进 `.doc/ops/evidence/` 后再 `worktree remove`。
|
||||
|
||||
只读盘点(不自动删除、不自动写 MATRIX):
|
||||
|
||||
```bash
|
||||
python3 ../../scripts/agentctl.py cleanup report # 主目录或任意同仓 cwd
|
||||
python3 ../../scripts/agentctl.py docs drift
|
||||
```
|
||||
|
||||
对 `verdict=ready` 的 worktree 由独立维护者执行 `agent-worktree.sh remove … --delete-branch`;拒绝则保留 cleanup_pending。daemon 未装载时用 `queue schedule --drain`(主目录 + 分支 dev)。
|
||||
@@ -0,0 +1,46 @@
|
||||
---
|
||||
name: agentctl-lease-write
|
||||
description: Write under agentctl leases and docs apply CAS. Use before any git write, shared-doc edit, or when hitting UNMANAGED_DOCUMENT_CHANGE / EVIDENCE_REQUIRED.
|
||||
---
|
||||
|
||||
# agentctl 租约写回
|
||||
|
||||
权威:[AGENTS §3–5](../../../AGENTS.md)、[操作规范](../../../.doc/ops/2026-09-21-agent-worktree-workflow.md)。
|
||||
|
||||
## 原则
|
||||
|
||||
- **任何仓库写**(含 `git add/commit`)必须在 `agentctl with` / MCP `lease_run` 租约内
|
||||
- CURRENT / FEATURE-MATRIX **只能** `docs apply`(行级 CAS;MATRIX 键为 `record_id`)
|
||||
- 直接 `git commit` 会被 agentctl-managed pre-commit hook 拒绝
|
||||
|
||||
## lease_run(CLI)
|
||||
|
||||
```bash
|
||||
python3 scripts/agentctl.py with \
|
||||
--task "$ID" \
|
||||
--resource path:scripts --resource path:.doc --resource git:index \
|
||||
-- bash -lc 'git add … && git commit -m "…"'
|
||||
```
|
||||
|
||||
MCP:`lease_run` 的 `command` 为 **argv 数组**(无额外 shell)。
|
||||
|
||||
## docs apply(行级)
|
||||
|
||||
```bash
|
||||
python3 scripts/agentctl.py docs snapshot --file .doc/ops/CURRENT.md --record "$RID"
|
||||
# expected_sha256 = snapshot.sha256;改 replacement 后:
|
||||
python3 scripts/agentctl.py docs apply --task "$ID" --request /tmp/req.json
|
||||
```
|
||||
|
||||
FEATURE-MATRIX 升 `done` 需要 `docs:approve` + 可核验 evidence(`git cat-file -e`),否则 `EVIDENCE_REQUIRED`。
|
||||
收口或合入含 MATRIX 的变更后跑 `python3 scripts/agentctl.py docs drift`:硬告警仅 `done→非 done`;不因任务结束自动升 done。
|
||||
|
||||
## 常见拒绝
|
||||
|
||||
| 码 | 处置 |
|
||||
|---|---|
|
||||
| `UNMANAGED_DOCUMENT_CHANGE` | 保留现场,先 snapshot/reconcile,勿覆盖 |
|
||||
| `BASE_CHANGED` | 重新 snapshot,基于新 sha 再 apply |
|
||||
| `AMBIGUOUS_RECORD` | 修重复 record_id / 模块名 |
|
||||
| `CAPABILITY_REQUIRED` | 任务缺 docs:admin / docs:approve |
|
||||
| `DOCUMENT_RECEIPT_REQUIRED` | 共享文档须经 apply 收据后再 commit |
|
||||
@@ -0,0 +1,51 @@
|
||||
---
|
||||
name: agentctl-session-start
|
||||
description: Start an Agent-System session under agentctl governance. Use at session start, when opening a worktree, or before any write to this repo.
|
||||
---
|
||||
|
||||
# agentctl 会话启动
|
||||
|
||||
权威规范:[AGENTS.md](../../../AGENTS.md)、[操作规范](../../../.doc/ops/2026-09-21-agent-worktree-workflow.md)、[CURRENT](../../../.doc/ops/CURRENT.md)。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. 读 `AGENTS.md`、`PROJECT.md`、`.doc/ops/CURRENT.md` 活跃摘要(勿跳过)。
|
||||
2. 核对管理面:
|
||||
|
||||
```bash
|
||||
python3 scripts/agentctl.py daemon status
|
||||
# 期望:status=ok;launchd 已装载时 manager.lock.held=true
|
||||
```
|
||||
|
||||
或 MCP 工具 `status`。
|
||||
|
||||
3. 刷新 CodeGraph 索引(fail-open;CLI 缺失可跳过):
|
||||
|
||||
```bash
|
||||
codegraph sync -q
|
||||
# 或:python3 scripts/agentctl.py hooks codegraph-sync
|
||||
```
|
||||
|
||||
跨文件定位优先用 CodeGraph MCP/`explore`;**grep 仍是完整性唯一权威**(假阴性时以 grep 为准)。
|
||||
|
||||
4. 若任务已存在:在注册 worktree 内工作,确认 `tasks.state=active`。
|
||||
5. **开工前需求重叠探测**(治理目录库):新设计或可能与其他对话重叠时:
|
||||
|
||||
```bash
|
||||
python3 scripts/agentctl.py catalog search --query '<关键词>'
|
||||
python3 scripts/agentctl.py catalog overlap --task "$ID" --statement '<设计原文>' [--requirement R-xxx] [--feature <record_id>] [--mutex <key>]
|
||||
# soft 命中须显式裁决后才可编码:
|
||||
python3 scripts/agentctl.py catalog overlap ack --task "$ID" --overlap <oid> --decision proceed|merge_into|supersede|defer --reason '...'
|
||||
```
|
||||
|
||||
硬重叠(同 mutex/feature/scope/R-ID)直接拒绝;向量层失败自动降级到 FTS5,不阻断。
|
||||
|
||||
6. 若新任务:跟 [agentctl-worktree-setup](../agentctl-worktree-setup/SKILL.md)。
|
||||
7. 任何仓库写 → [agentctl-lease-write](../agentctl-lease-write/SKILL.md);合入 → [agentctl-integrate-closeout](../agentctl-integrate-closeout/SKILL.md)。
|
||||
|
||||
## 禁止
|
||||
|
||||
- 主目录直接开发提交;未授权 `git push` / 晋升 test/main
|
||||
- 绕过 `docs apply` 改 CURRENT / FEATURE-MATRIX
|
||||
- 卸载或重启 launchd coordinator(除非用户明示)
|
||||
- 未执行 `catalog overlap` / 未裁决 soft 命中即编码(有 `--requirement`/`--intent`/`--feature`/`--mutex` 绑定时机器强制)
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
name: agentctl-worktree-setup
|
||||
description: Create an agentctl task worktree, register scopes/capabilities, and claim CURRENT. Use when starting a new feature/fix task in Agent-System.
|
||||
---
|
||||
|
||||
# agentctl 建场
|
||||
|
||||
权威:[操作规范](../../../.doc/ops/2026-09-21-agent-worktree-workflow.md)。
|
||||
|
||||
## 命令序列
|
||||
|
||||
```bash
|
||||
cd /path/to/Agent-System # 主目录(dev)
|
||||
D=$(git rev-parse HEAD)
|
||||
ID=<task-id-YYYY-MM-DD>
|
||||
WT=.worktrees/$ID
|
||||
# 推荐入口:自动 best-effort codegraph init(后台;CLI 缺失不阻断)
|
||||
./scripts/agent-worktree.sh create feature/$ID
|
||||
# 等价:git worktree add -b feature/$ID "$WT" "$D"
|
||||
cd "$WT"
|
||||
python3 ../../scripts/agentctl.py task register \
|
||||
--id "$ID" --owner <Owner> \
|
||||
--scope scripts --scope .doc \
|
||||
--capability docs:publish
|
||||
# 需要整文/行级 admin 时再加 --capability docs:admin;证据升 done 加 docs:approve
|
||||
# 若已知需求/功能绑定,追加:
|
||||
# --requirement R-<slug> --intent '<设计原文>' --feature <record_id> --mutex <key>
|
||||
# 有 soft 重叠时 register 会 OVERLAP_ACK_REQUIRED:先 catalog overlap + ack 再重试 register
|
||||
codegraph sync -q # 若建场已 init,此处只需 sync;缺失 CLI 可跳过
|
||||
```
|
||||
|
||||
## 开工前重叠裁决(catalog)
|
||||
|
||||
```bash
|
||||
python3 ../../scripts/agentctl.py catalog overlap \
|
||||
--task "$ID" --statement '<新设计原文>' \
|
||||
[--requirement R-xxx] [--feature <record_id>] [--mutex <key>]
|
||||
# hard → 换 mutex/合并到持有者任务;soft → ack 留痕
|
||||
python3 ../../scripts/agentctl.py catalog ack \
|
||||
--task "$ID" --overlap <oid> \
|
||||
--decision proceed|merge_into|supersede|defer \
|
||||
--reason '<理由>'
|
||||
```
|
||||
|
||||
## CURRENT 认领
|
||||
|
||||
优先用一层封装(内部仍走 `docs apply` CAS):
|
||||
|
||||
```bash
|
||||
python3 ../../scripts/agentctl.py claim new \
|
||||
--task "$ID" --owner <Owner> --mutex <mutex> \
|
||||
[--branch feature/$ID] [--worktree "$WT"] [--replace]
|
||||
```
|
||||
|
||||
手工 `docs snapshot` + `docs apply` 仍可用;行已存在且内容不同时需 `--replace`。
|
||||
|
||||
## short-term 模板字段
|
||||
|
||||
`status`、`write_scope`、`mutex`、`base_dev_sha`、`review_state`/`integration_state`/`deployment`/`cleanup`/`remote_sync`。命名 `.doc/ops/short-term/YYYY-MM-DD-<slug>.md`。
|
||||
|
||||
## 注意
|
||||
|
||||
- 从确切 `dev` SHA 创建,不从他人 feature 分支启动
|
||||
- 重叠 path/mutex 只允许一个写者
|
||||
- CodeGraph 索引是加速器:有假阴性;穷举调用方仍用 grep
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
name: jev-decide
|
||||
description: Use jev-service typed decisions (choice/noul/numeric with probabilities) for Agent-System governance classification. Use when choosing task tier, validation level, reject-code routing, or other closed-enum judgments.
|
||||
---
|
||||
|
||||
# jev-decide(治理决策)
|
||||
|
||||
依赖 MCP 服务器 `jev`([`scripts/mcp/jev-mcp.mjs`](../../../scripts/mcp/jev-mcp.mjs))。凭证在本机 `~/.secrets/jev/`(`api.key`、`base-url`),**禁止**写入仓库、commit 或聊天。
|
||||
|
||||
## 何时用
|
||||
|
||||
输入是情境文本、输出是**封闭枚举 / yes-no / 分桶数值**时调用 `jev_decide`,例如:
|
||||
|
||||
| 决策点 | 建议 questions |
|
||||
|---|---|
|
||||
| 任务分级(是否开 worktree) | `choice`:`info_reply` / `single_task` / `cross_module` |
|
||||
| 验证层级(验证契约) | `choice`(可多题):`doc` / `script` / `go` / `frontend` / `migration` / `product_pi` |
|
||||
| 拒绝码处置 | `choice`:`reconcile` / `re_snapshot` / `fix_record_id` / `request_capability` / `abort` |
|
||||
| 是否 blocker / 是否触碰重验面 | `noul` |
|
||||
|
||||
不适合:需要解释链、多步规划、自由文本生成——那些走大模型或 agentctl 确定性门禁。
|
||||
|
||||
## 调用约定
|
||||
|
||||
1. 可选先 `jev_health`;失败则本机判断,勿阻塞写路径。
|
||||
2. `jev_decide`:同一情境的多问合成一次请求。
|
||||
3. 问句**正向措辞**,避免双重否定。
|
||||
4. 置信度路由:
|
||||
- `confidence >= 0.9` 且 top1−top2 ≥ 0.15 → 可采用
|
||||
- 否则 → agent 自行按规范裁定,把 jev 结果当参考
|
||||
5. 401/超时/`answers.*.error` → 降级到本机判断;勿把决策失败变成业务失败。
|
||||
|
||||
## 示例(任务分级)
|
||||
|
||||
```json
|
||||
{
|
||||
"context": "用户请求:给 CURRENT 加一行认领说明,不改代码",
|
||||
"questions": {
|
||||
"tier": {
|
||||
"type": "choice",
|
||||
"question": "This request matches which AGENTS task tier?",
|
||||
"options": ["info_reply", "single_task", "cross_module"]
|
||||
},
|
||||
"needs_worktree": {
|
||||
"type": "noul",
|
||||
"question": "Does this require a new feature/fix worktree?"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
权威矩阵仍以 [AGENTS.md](../../../AGENTS.md)、[验证契约](../../../.doc/ops/2026-09-21-validation-contract.md) 为准;jev 只加速封闭枚举分类,不替代机器门禁(admit/hooks/docs apply)。
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
name: pi-subagent-dispatch
|
||||
description: Dispatch gmktec PI analysis/review/test subagents via project MCP pi-subagents (roles/run/result). Use when delegating research, planning, reviews, diagnosis, test_run, acceptance_check, or report work—not for code implementation.
|
||||
---
|
||||
|
||||
# PI Subagent 派发
|
||||
|
||||
权威:[模型配置](../../../.doc/ops/2026-09-24-subagent-model-config.md)、[执行器说明](../../../.doc/ops/2026-09-24-pi-subagent-executor.md)、[流程规范](../../../.doc/ops/2026-09-24-subagent-workflow-standard.md)。客户端规则:[pi-subagents](../../rules/pi-subagents.mdc)。阶段落盘:[subagent-stage-record](../subagent-stage-record/SKILL.md)。
|
||||
|
||||
**Cursor Auto 独占代码实施与修复**;本 skill 只走本机 PI 子任务。
|
||||
|
||||
## 调用序列
|
||||
|
||||
1. `pi_subagent_roles` — 只读预览角色/模型(不调 PI)。
|
||||
2. 选 `role_id`(research → planning → reviews → diagnosis → test_run / acceptance_check → report)。
|
||||
3. (推荐)`agentctl pi packet` 生成派发包;**不**触发 run:
|
||||
```bash
|
||||
python3 -B scripts/agentctl.py pi packet \
|
||||
--task "$ID" --role research \
|
||||
--goal '…' --authorization-ref 'user:…' \
|
||||
--source-sha "$(git rev-parse HEAD)" \
|
||||
[--input-file …] [--approved-command '…']… \
|
||||
--request-id "$RID" --write
|
||||
# → .doc/test-reports/assets/pi-subagents/<task>/<request>/packet.json
|
||||
```
|
||||
4. `pi_subagent_run` — 按 packet 字段在 agentctl 租约下异步启动。
|
||||
5. `pi_subagent_result` — 取回收据;轮询至终态。
|
||||
|
||||
CLI 等价:`python3 -B scripts/pi_subagents.py roles|run|result`;`run` 必须包在 `agentctl with --resource path:.doc/test-reports/assets/pi-subagents/<task>/<request>` 内。
|
||||
|
||||
## 请求字段(MCP `pi_subagent_run`)
|
||||
|
||||
外层:`worktree`(已登记任务工作区绝对路径)、`task_id`、`request` 对象。
|
||||
|
||||
`request` 必填:
|
||||
|
||||
| 字段 | 约束 |
|
||||
|---|---|
|
||||
| `role_id` | 配置 §3 中 enabled 角色 |
|
||||
| `request_id` | 任务内稳定唯一;同参重放不重复调模型 |
|
||||
| `goal` | 具体目标;子任务不依赖主会话未传入历史 |
|
||||
| `authorization_ref` | 可回链真实用户授权,禁止日志自授 |
|
||||
| `source_sha` | **完整** 40-hex 提交;禁止 `HEAD`/分支名/短 hash |
|
||||
| `input_files` | 已跟踪 UTF-8 普通文件相对路径数组 |
|
||||
| `timeout_seconds` | 正整数 |
|
||||
|
||||
测试角色(`test_run` / `acceptance_check`)另需:
|
||||
|
||||
- `approved_commands`:argv 数组的数组(如 `[["go","test","-short","./"]]`)
|
||||
- `plan_digest`:外部已批准计划的 SHA-256 hex
|
||||
|
||||
禁止静默 `model_override`;临时改模型写任务 override 并说明用户来源。
|
||||
|
||||
## 租约与输出
|
||||
|
||||
- 资源:`path:.doc/test-reports/assets/pi-subagents/<task_id>/<request_id>`
|
||||
- 产物:`receipt.json`、`report.md`、命令日志(同目录)
|
||||
- 裸调 `run`(无租约)被拒绝
|
||||
|
||||
## 状态分离(红线)
|
||||
|
||||
| 字段 | 含义 |
|
||||
|---|---|
|
||||
| `run_status` | running / succeeded / failed / cancelled / unknown |
|
||||
| `verdict` | pass / changes_required / blocked / not_applicable |
|
||||
| `review_state` | 阶段门禁;模型 succeeded **仅** pending |
|
||||
|
||||
测试 `commands_passed`/`pass` 只针对批准命令证据,不能直接赋给任务 `acceptance`。
|
||||
|
||||
## 常见拒绝码(执行器权威)
|
||||
|
||||
| 码 | 处置 |
|
||||
|---|---|
|
||||
| `INVALID_SOURCE_SHA` | 换完整提交 hash |
|
||||
| `APPROVED_COMMANDS_REQUIRED` | 补 approved_commands + plan_digest |
|
||||
| `MINIMAX_ROLE_FORBIDDEN` | 不把 M3 用于关键角色 |
|
||||
| `INPUT_NOT_TRACKED` / `PATH_OUT_OF_SCOPE` | 收窄 input_files |
|
||||
| `CONCURRENCY_LIMIT` | 串行或等空闲槽 |
|
||||
| `ORPHAN_RUNNING` | 先核进程/副作用,勿盲目重派 |
|
||||
|
||||
Cursor hooks 对形状错误可能 `permission=ask`(advisory);**硬拒绝以执行器为准**。
|
||||
|
||||
## 禁止
|
||||
|
||||
- 把 implementation 派给 PI
|
||||
- 自动换模型 / 伪造 lease / 递归把本修复再派给 PI worker
|
||||
- 用模型叙事冒充 PASS;审查结论须带回报告路径与 receipt 字段
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
name: subagent-stage-record
|
||||
description: Record PI/Cursor stage handoffs using the subagent stage template (dispatch packet, return, S0–S9 receipt, R-AC-T mapping). Use after PI results, before gate advances, or when closing a multi-stage task.
|
||||
---
|
||||
|
||||
# Subagent 阶段记录
|
||||
|
||||
权威模板:[subagent-stage-record.md](../../../.doc/ops/templates/subagent-stage-record.md);流程:[协作规范](../../../.doc/ops/2026-09-24-subagent-workflow-standard.md)。派发入口:[pi-subagent-dispatch](../pi-subagent-dispatch/SKILL.md)。
|
||||
|
||||
原则:**一步一记录,不必一步一文件**。小任务可把适用段落并入任务主文档;跨模块才拆独立审查/测试/验收证据。
|
||||
|
||||
## 何时写
|
||||
|
||||
- 每次 `pi_subagent_run` 前后:派发包 + 回传
|
||||
- 阶段门禁推进前:S0–S9 收据行
|
||||
- 收口前:R→AC→改动→审查→T→运行验收映射
|
||||
|
||||
## 派发包(最小字段)
|
||||
|
||||
复制到任务文档并填实值:
|
||||
|
||||
- `parent_task_id` / `subtask_id` / `stage_id` / `role_id`
|
||||
- 配置路径 / `config_revision` / `config_sha256`(来自 roles 或 receipt)
|
||||
- 解析后的 provider/model;任务 override 与用户来源
|
||||
- 目标、非目标、授权来源、交付终点
|
||||
- 输入版本:R-ID / AC-ID / 方案版本 / `base_sha` / `head_sha` 或 `source_sha`
|
||||
- cwd / branch / allowed_paths / 只读或写入 / mutex
|
||||
- 完成条件、输出路径、预算与异常处理
|
||||
|
||||
## 子任务回传
|
||||
|
||||
- PI `run_id` / producer / 起止时间
|
||||
- `configured_model` / `actual_model`(不可观察填 `unknown`)
|
||||
- `run_status` 与 `verdict` **分列**(不得把退出成功当质量通过)
|
||||
- 结论与依据、证据链接、脱敏范围
|
||||
- 未覆盖项、风险、遗留进程/产物、接管建议
|
||||
|
||||
只读子 Agent 结论由主 Agent 转存时:保留 `agent_id` 与原结论,注明「由主 Agent 转存」。
|
||||
|
||||
## 阶段收据表
|
||||
|
||||
| 阶段 | 输入版本 | 产物/证据 | producer | reviewer/独立性 | 决定 | 下一步 |
|
||||
|---|---|---|---|---|---|---|
|
||||
| S0–S9 适用项 | | | | independent / self_review / not_required | pass / changes_required / blocked / not_applicable | |
|
||||
|
||||
未执行阶段写 `not_applicable` + 原因。报告存在不自动满足门禁。
|
||||
|
||||
## 需求追踪
|
||||
|
||||
| R-ID | AC-ID | 改动/版本 | 审查 | T-ID / 结果 | 运行验收 | acceptance_owner |
|
||||
|---|---|---|---|---|---|---|
|
||||
| | | | | | | |
|
||||
|
||||
## 与任务五态
|
||||
|
||||
继续用任务模板的 `status`、`review_state`、`integration_state`、`deployment`、`cleanup`、`remote_sync`;额外记 `phase`、`acceptance`、待回收 `subtask_id`。`done` 取决于授权交付终点,不因会话结束自动完成。
|
||||
+7
-4
@@ -11,10 +11,10 @@
|
||||
.doc/
|
||||
README.md ← 本文件(总地图)
|
||||
status/ ← 模块/功能完成度 SSOT
|
||||
audit/ ← 问题发现与分析
|
||||
audit/ ← 问题发现与分析、ISSUES.md 问题/修复台账
|
||||
remediation/ ← 整改方案与发布缺口
|
||||
archive/ ← 历史(只增不删)
|
||||
ops/ ← 活协作(任务、交接、调研)
|
||||
ops/ ← 活协作(任务、交接、调研;lessons/ 开发经验)
|
||||
system-design/ ← 模块架构深读
|
||||
adr/ ← 架构决策
|
||||
backlog/ ← 产品 backlog(非阻塞)
|
||||
@@ -33,6 +33,7 @@
|
||||
|
||||
| 我要… | 读这里 |
|
||||
|--------|--------|
|
||||
| Subagent 模型配置 / 流程 | [可调整模型配置](ops/2026-09-24-subagent-model-config.md) · [PI 执行器](ops/2026-09-24-pi-subagent-executor.md) · [流程草案](ops/2026-09-24-subagent-workflow-standard.md) · [研究依据](audit/2026-09-24-subagent-workflow-research.md) |
|
||||
| 规则来源/生效版本 | [规范登记](ops/2026-09-21-policy-registry.md) |
|
||||
| 选择测试/报告范围 | [验证契约](ops/2026-09-21-validation-contract.md) |
|
||||
| 任务模板与会话收口 | [任务模板](ops/templates/short-term-task.md) · [收口清单](ops/templates/session-close-checklist.md) |
|
||||
@@ -40,13 +41,15 @@
|
||||
| 当前在做什么 | [ops/CURRENT.md](ops/CURRENT.md) |
|
||||
| 模块完成度 | [status/FEATURE-MATRIX.md](status/FEATURE-MATRIX.md) |
|
||||
| 发布 blocker | [remediation/gap-matrix.md](remediation/gap-matrix.md) |
|
||||
| 问题历史、修复经过 | [问题台账](audit/ISSUES.md) · [闭环规范](ops/2026-09-23-issue-learning-workflow.md) |
|
||||
| 开发注意事项与经验检索 | [经验索引](ops/lessons/INDEX.md) |
|
||||
| 审计/问题分析 | [audit/INDEX.md](audit/INDEX.md) |
|
||||
| 整改方案 | [remediation/INDEX.md](remediation/INDEX.md) |
|
||||
| 历史归档 | [archive/README.md](archive/README.md) |
|
||||
| 架构设计 | [system-design/README.md](system-design/README.md) |
|
||||
| 用错误码定位失败 | [错误码目录](system-design/2026-09-28-error-code-catalog.md) |
|
||||
| 测试报告 | [test-reports/](test-reports/) |
|
||||
| 历史功能设计 | [archive/design/superpowers/](archive/design/superpowers/) |
|
||||
| Herdr 角色、审批与备援 | [ops/2026-09-13-herdr-agent-roster.md](ops/2026-09-13-herdr-agent-roster.md) |
|
||||
|
||||
---
|
||||
|
||||
@@ -68,6 +71,6 @@ audit(问题)→ remediation(方案)→ ops/short-term(任务)
|
||||
→ test-reports(验收)→ archive(关闭证据)
|
||||
```
|
||||
|
||||
状态字段:`planned | in_progress | blocked | done | cancelled`
|
||||
任务状态字段:`planned | in_progress | blocked | done | cancelled`。问题以 issue_state、经验以 lesson_state 独立记录,取值与转换见 [闭环规范](ops/2026-09-23-issue-learning-workflow.md);研究任务完成不关闭待修问题。
|
||||
|
||||
会话结束不等于任务完成;只有 done/cancelled 任务归档。CURRENT 保留最多 3 项焦点及活跃/阻塞/待集成/待清理事项,完成认领和长证据迁入 [历史快照](archive/ops/2026-09-21-current-history.md)。移动文档同步修复相对链接,保留证据与来源。规范生命周期另用 proposed/approved/active/deprecated;工具能力另用 manual/enforced。
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# ADR:最终成果保险库(FAV)
|
||||
|
||||
## 状态
|
||||
|
||||
已接受(2026-09-14,落地计划 V0–V6)
|
||||
|
||||
## 背景
|
||||
|
||||
运行库 PostgreSQL 与 workspace 投影会一起丢失或错挂。需要独立保存**已确认终态**的精确字节,但不能成为第三套完整业务真相源,也不能用目录扫描猜测“最终文件”。
|
||||
|
||||
## 决策
|
||||
|
||||
1. **三层权威**:PostgreSQL 管项目/权限/工作流/版本关系;workspace 是可清理投影;FAV 只对已归档 payload、manifest、来源证据和删除状态权威。
|
||||
2. **无 tenant_id**:安全边界沿用 `environment + project_members + role-admin`。未来组织层另立 ADR。
|
||||
3. **事件准入**:只接受方案准入表中的数据库事实。显式 publish/pin 不能绕过终态 allowlist。禁止扫描 workspace。
|
||||
4. **同事务冻结**:终态事务把精确 payload/SHA 写入 staging 并写 unpublished outbox;publisher 不得重读可变消息行。
|
||||
5. **union-deny 删除**:运行库删除账本或 vault tombstone 任一侧删除即拒绝读取/恢复。
|
||||
6. **恢复**:只进 scratch 库,默认 `recover-as-collection`。禁止 GET 自动写回或覆盖现有 head。
|
||||
7. **互补**:FAV、migration corpus、完整 DB backup/PITR 互相不能替代。不作为 409/split-brain 绕行。
|
||||
|
||||
## 后果
|
||||
|
||||
- 实现从 `feature/final-artifact-vault` 推进;mutex=`artifact-vault`。
|
||||
- Goose 从 **00034** 增加 FAV 表(00033 已被 task-run 治理占用)。
|
||||
- 降级读取默认关闭(`FAV_DEGRADED_READ`),Unit A 纠挂完成前不得对现网开启。
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: "Agent 规范整体审查"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
owner: Codex
|
||||
branch: feature/agent-policy-review
|
||||
worktree: .worktrees/agent-policy-review
|
||||
base_dev_sha: a241e838150f218f3a09d3523f93291b847d45fd
|
||||
write_scope: [.doc/ops/short-term/2026-09-21-agent-policy-review.md, .doc/archive/ops/2026-09-21-agent-policy-review.md, .doc/audit/2026-09-21-agent-policy-review.md, .doc/ops/CURRENT.md]
|
||||
mutex: agent-policy-review
|
||||
deployment: not_required
|
||||
cleanup: retained-with-reason
|
||||
---
|
||||
|
||||
# Agent 规范整体审查
|
||||
|
||||
## 目标与范围
|
||||
|
||||
评估生效规范的可完善之处,形成有依据的新增、删除、修改清单。本轮使用 ce-doc-review 的只读审查流程;不修改 AGENTS/PROJECT/客户端规则,不实现锁管理或改业务代码。
|
||||
|
||||
## 已确定约束
|
||||
|
||||
- 全部新增修改使用 .worktrees;主目录留给 dev 集成与运行。
|
||||
- 锁先统一入口/提交门禁防误改,OS 权限隔离后续实施。
|
||||
- 审查不等于实现或部署授权;已有未合入规范收口和 .locks 方案保留原分支。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 启动链、当前 Git、规范与模板盘点。
|
||||
2. [x] 一致性、可执行性、范围、安全及故障场景复核。
|
||||
3. [x] 核实保留发现,形成增删改建议与实施优先级。
|
||||
4. [x] 文档校验、归档、本地提交。
|
||||
|
||||
## 验收
|
||||
|
||||
- 每条保留发现有当前源文件或明确缺失证据、实际后果和建议修改。
|
||||
- 区分已生效规则、尚待实现工具和未合入草案;不把建议当现状。
|
||||
- 未修改主目录跟踪文件、运行锁、服务或用户数据。
|
||||
|
||||
## 结果与交接
|
||||
|
||||
- [整体审查](../../audit/2026-09-21-agent-policy-review.md):10 组增删改建议、2 项安全观察;保留已确定的 worktree 与 L1-first 选择。
|
||||
- 五个独立会话内视角已返回;主审核对引用与实际命令/脚本。文档原规则未改,自动化未实施。
|
||||
- 检查项:新增文档相对链接、git diff --check;未运行产品测试,不作运行验收声明。
|
||||
- 本任务 CURRENT 快照标 done,未占共享集成槽位;本地分支保留供审核,未合入 dev、未 push。
|
||||
- 需要执行修改时先按第一批消除冲突,再处理减负及既有工具实现;不要将本报告直接视为已生效规则。
|
||||
@@ -0,0 +1,43 @@
|
||||
---
|
||||
title: "采纳 Agent worktree 工作规范"
|
||||
status: done
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
owner: Codex
|
||||
branch: feature/agent-workflow-governance-plan
|
||||
worktree: .worktrees/feature-agent-workflow-governance-plan
|
||||
mutex: agent-workflow-governance
|
||||
---
|
||||
|
||||
# 采纳 Agent worktree 工作规范
|
||||
|
||||
## 授权与范围
|
||||
|
||||
用户于 2026-09-21 确认“提交吧,之后按这套执行”。延续原治理任务,在原 dev 派生的独立 worktree 内将方案采纳为生效规则,提交并合入本地 dev。仅修改规范、模板和治理记录。
|
||||
|
||||
本次不将 W1–W4 的自动化开发宣称已完成;它们保留在实施任务中。主目录仍有其他任务未提交改动,使用临时集成 worktree 合入纯文档,不迁移原任务、不改变业务运行态、不 push。
|
||||
|
||||
## 步骤
|
||||
|
||||
1. [x] 核对主目录现场、原方案提交与集成槽位。
|
||||
2. [x] 同步 AGENTS、PROJECT、Cursor 规则、操作规范与模板。
|
||||
3. [x] 文档检查、提交、独立 worktree 合入 dev。
|
||||
4. [x] 更新验收/交接及清理状态。
|
||||
|
||||
## 验收
|
||||
|
||||
- [x] 单 Agent 主目录开发例外已移除,生效规则可从启动链发现。
|
||||
- [x] 创建明确来自 dev;测试提交、共享服务串行、部署及安全清理条件可执行。
|
||||
- [x] 自动化能力保持 planned;主目录其他任务未提交改动不被纳入提交。
|
||||
- [x] 本地 dev 含本次规范提交;未 push,未重建服务。
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [方案](../../remediation/2026-09-21-agent-workflow-governance-plan.md)
|
||||
|
||||
## 结果
|
||||
|
||||
- 规则提交 `048bbe4a`,验证的合并候选及首次 dev 合入 `83e22a70`。
|
||||
- [文档验收](../../test-reports/2026-09-21-agent-workflow-governance-adoption-test-report.md)。
|
||||
- 主目录旧任务保留;临时 dev 集成工作区保留到原 owner 可安全切回 dev,见 [交接](../../ops/handoffs/2026-09-21-agent-workflow-governance-plan.md)。
|
||||
- 收口提交合入后普通清理本任务和候选工作区,实际结果记录共同 Git 目录的治理操作收据。未 push;deployment=not_required。
|
||||
@@ -0,0 +1,167 @@
|
||||
---
|
||||
title: "dev rebuild 从临时 worktree 挂载空数据根导致正文投影 409"
|
||||
status: done
|
||||
created: 2026-09-14
|
||||
updated: 2026-09-14
|
||||
severity: critical
|
||||
---
|
||||
|
||||
# dev rebuild 从临时 worktree 挂载空数据根导致正文投影 409
|
||||
|
||||
## 现象
|
||||
|
||||
用户刷新项目 143 后,前端请求:
|
||||
|
||||
```text
|
||||
GET /api/v1/docgov/documents/doc_proj143_intake/content 409
|
||||
DOCUMENT_CONTENT_PROJECTION_MISSING
|
||||
docgov: document content projection missing
|
||||
```
|
||||
|
||||
错误发生在 `projectDocuments.ts` → `controlledDocHydrate.ts` 的受控正文水合链。它不是并发编辑的 `HEAD_CONFLICT`,也不是此前已修过的 canonical hash drift。
|
||||
|
||||
本轮只做只读现场核对与整改设计:没有操作用户会话、没有修改数据库/正文、没有重建共享容器。
|
||||
|
||||
## 结论
|
||||
|
||||
直接根因是 **dev 应用、PI Runner、Cursor Runner 被重建成挂载临时集成 worktree 的空 `data/dev`,而 PostgreSQL 仍沿用原 dev 持久卷**,形成数据库与文件事实源的 split-brain:
|
||||
|
||||
```text
|
||||
PostgreSQL persistent volume
|
||||
document_records.work_dir=/app/data/workspaces/bizdev/intake_1789270446856290128
|
||||
│
|
||||
├─ 主仓 data/dev:output.md 存在,SHA 与 DB/head 一致
|
||||
│
|
||||
└─ 当前容器 /app/data:绑定 /tmp/as-dev-wf409-merge/data/dev,文件不存在
|
||||
```
|
||||
|
||||
`loadControlledDocumentContent` 先取得账本 head,再调用 `InspectProjection`;容器内看不到 `output.md`,因此正确分类为 `MISSING` 并返回 409。前端只是如实暴露后端错误,不是本次根因。
|
||||
|
||||
## 现场证据
|
||||
|
||||
### E1 — 容器挂载源是临时 worktree
|
||||
|
||||
2026-09-14 08:54 UTC 的 `docker inspect shuimu-agent-app-dev`:
|
||||
|
||||
| 项 | 现场值 |
|
||||
|---|---|
|
||||
| Compose working dir | `/tmp/as-dev-wf409-merge` |
|
||||
| Compose config | `/tmp/as-dev-wf409-merge/docker-compose.dev.yml` |
|
||||
| app `/app/data` source | `/tmp/as-dev-wf409-merge/data/dev` |
|
||||
| pi-agent `/app/data/workspaces` source | `/tmp/as-dev-wf409-merge/data/dev/workspaces` |
|
||||
| cursor-agent `/app/data/workspaces` source | `/tmp/as-dev-wf409-merge/data/dev/workspaces` |
|
||||
| app created | `2026-09-14T08:40:44Z` |
|
||||
|
||||
数据库容器的数据仍来自命名卷 `agent-dev-context-pgdata`,不会随 Compose 工作目录切换。由此产生“旧数据库 + 新空文件根”的不一致组合。
|
||||
|
||||
### E2 — 项目 143 数据本身当前完整
|
||||
|
||||
`document_records`:
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| doc_id | `doc_proj143_intake` |
|
||||
| work_dir | `/app/data/workspaces/bizdev/intake_1789270446856290128` |
|
||||
| content_sha256 | `f283ba94c9c037897f021960f51abacee7242c3db8d10f9f2a5e32cde6acf039` |
|
||||
| updated_at | `2026-09-14 05:14:10.302146+00` |
|
||||
|
||||
账本 open version 1 的 head snapshot 302 是人工修订,SHA 同为 `f283...f039`;主仓文件:
|
||||
|
||||
```text
|
||||
/home/weichen/projects/Agent-System/data/dev/workspaces/bizdev/intake_1789270446856290128/output.md
|
||||
size=40075
|
||||
sha256=f283ba94c9c037897f021960f51abacee7242c3db8d10f9f2a5e32cde6acf039
|
||||
```
|
||||
|
||||
同一路径在当前 app 容器内 `stat` 返回 `No such file or directory`。所以无需再次对项目 143 做内容修复;需要恢复正确数据根挂载。
|
||||
|
||||
### E3 — 影响不是单文档
|
||||
|
||||
对 dev 数据库 100 条“非模板且 work_dir 非空”的记录做只读比较:
|
||||
|
||||
| 根目录 | aligned | missing |
|
||||
|---|---:|---:|
|
||||
| 主仓 `/home/weichen/projects/Agent-System/data/dev` | 32 | 68 |
|
||||
| 当前容器挂载 `/tmp/as-dev-wf409-merge/data/dev` | 0 | 100 |
|
||||
|
||||
主仓下的 68 条 missing 包含历史测试/临时路径,不能直接等同于 68 个真实用户缺陷;但当前容器对本次抽样 **100/100 都不可见**,足以确认环境级事故。恢复前任何真实文档读取或 PI 写入都不可信。
|
||||
|
||||
错误根在容器启动后已出现 27 个文件,其中 9 个 CAS blob 的 mtime 为 `08:40:45 UTC`;虽然 08:54 UTC 尚未找到新的 `output.md`,错误根已经不是可直接丢弃的“绝对空目录”,恢复前仍须做完整差异保全。
|
||||
|
||||
只读核对显示 test/main 当前 app 与 PI Runner 仍挂主仓 `data/test`、`data/main`,本轮没有观察到同样的运行事故;但其 Compose 仍使用相对 bind,仍受同一设计缺陷影响。
|
||||
|
||||
### E4 — 健康检查假阳性
|
||||
|
||||
同一时刻 `/health` 与 `/ready` 都返回 200,只检查数据库、schema 和 task store;未验证:
|
||||
|
||||
- 容器绑定的数据根身份;
|
||||
- app 与 runner 是否挂载同一根;
|
||||
- 活跃项目的正文投影是否可达;
|
||||
- 数据库记录与文件根是否属于同一环境实例。
|
||||
|
||||
因此“healthy + schema 33”不能证明文档运行态可用。
|
||||
|
||||
## 根因分析
|
||||
|
||||
### R1 — Compose 相对 bind mount 与调用 worktree 耦合(直接根因)
|
||||
|
||||
`docker-compose.dev.yml` 使用:
|
||||
|
||||
```yaml
|
||||
- ./data/dev:/app/data
|
||||
- ./data/dev/workspaces:/app/data/workspaces
|
||||
```
|
||||
|
||||
Compose 按 project working directory 解析相对路径。`scripts/env-service.sh` 又把 `ROOT_DIR` 定义为脚本所在 worktree 并 `cd` 进去,所以从任何复制/linked worktree 执行 `dev rebuild`,都会把该 worktree 自己的 `data/dev` 当成运行数据根。
|
||||
|
||||
### R2 — 纪律是文档约束,不是可执行门禁
|
||||
|
||||
`scripts/agent-worktree.sh` 只打印“禁止在此目录运行 env-service”,`AGENTS.md` 也规定 worktree 不得操作共享 Docker;但 `env-service.sh` 没有检测 linked worktree、主 worktree、分支、数据根或集成槽位。一次误调用即可静默替换全套容器挂载。
|
||||
|
||||
### R3 — 数据库与文件没有共享存储身份
|
||||
|
||||
数据库使用稳定 named volume;正文使用随调用目录变化的 bind mount。两者没有共同的 environment/storage UUID,也没有启动握手,因此任意一个被指向另一份状态时,进程仍可启动并连接成功。
|
||||
|
||||
### R4 — 账本权威仍被兼容投影阻断
|
||||
|
||||
当前设计声明 ledger head 是权威正文,但 GET 在账本存在时仍要求 `output.md` 投影必须存在且 aligned。于是兼容投影丢失会阻断 UI 读取权威账本。该 fail-closed 对真实 fork 有价值,却把“可安全重建的 missing”与“内容分叉”按同样的可用性后果处理。
|
||||
|
||||
### R5 — 正文更新仍是非原子双写
|
||||
|
||||
人工 PATCH 先提交 PostgreSQL 账本,再单独写 `output.md`;候选 commit/reject 也采用 DB 状态与文件投影分步更新。失败后只依赖同幂等键重试,没有持久 projection job/status 和后台补偿。即使修复本次挂载问题,进程崩溃、权限错误或磁盘故障仍可能再次留下 head 已更新、投影缺失的状态。
|
||||
|
||||
### R6 — 发布验收没有“从不同源码目录 rebuild 后仍接回同一状态”的负例
|
||||
|
||||
既有真实 UI 验收验证过 restart 后恢复,但 restart 不会重新解析 Compose bind mount;本次事故由 rebuild/recreate 触发。现有门禁没有覆盖 linked worktree、临时集成目录或错误数据根的启动拒绝。
|
||||
|
||||
## 为什么会“每次修改后又出现”
|
||||
|
||||
修改本身并不会删除项目 143 正文。本次时间线表明:最新人工修订和主仓 `output.md` 在 05:14 UTC 已一致落盘;08:40 UTC 后续 dev rebuild 把运行容器切到另一份空数据根,刷新才出现 409。
|
||||
|
||||
因此用户感知的“改完再刷新就坏”来自两个事件经常相邻:开发修改 → Agent 在临时 worktree 合并/rebuild → Compose 改绑数据目录。只修某个文档、某个 hydrate effect 或某次 hash 漂移,都无法阻止它复发。
|
||||
|
||||
## 严重度与影响
|
||||
|
||||
`critical`:
|
||||
|
||||
- dev 环境所有受控正文、工作流产物和 runner 工作区均可能不可见或写入错误根;
|
||||
- 错误根上的新输出可能与主仓状态分叉;
|
||||
- health/ready 仍为绿色,集成报告可能产生假 PASS;
|
||||
- test/main 使用同类相对 bind 写法,设计缺陷可横向复制,虽本轮未观察其被错挂载。
|
||||
|
||||
## 关联整改
|
||||
|
||||
- Remediation: [dev 运行数据根隔离与文档投影自愈整改](../remediation/2026-09-14-dev-runtime-data-root-and-projection-remediation.md)
|
||||
- Short-term: [dev runtime data root guard 诊断与设计](../ops/short-term/2026-09-14-dev-runtime-data-root-guard.md)
|
||||
- 前序问题: [项目 143 canonical hash 漂移](./2026-09-14-project143-controlled-content-404.md)
|
||||
|
||||
## 开放问题
|
||||
|
||||
- 恢复前需再次冻结并备份错误根,确认 08:40 UTC 后是否已有新会话、附件、runner 输出或 agent session 写入;08:54 UTC 抽样未发现 `output.md`,不能替代完整差异清单。
|
||||
- test/main 当前挂载源需在实施 Unit A 只读核对;本轮未扩大操作范围。
|
||||
|
||||
## 审查附记(2026-09-14 ~09:23 UTC)
|
||||
|
||||
- 现场复核:`shuimu-agent-app-dev` 仍 created `08:40:44Z`,bind source 仍为 `/tmp/as-dev-wf409-merge/data/dev`;`/health` `/ready` 仍 200,`schema_version=33`。
|
||||
- 主仓 CURRENT 集成槽仍为 `implementer_cursor` / `e2e`。worktree 副本不得写成 idle。
|
||||
- 方案已审查修订:见 [整改方案](../remediation/2026-09-14-dev-runtime-data-root-and-projection-remediation.md)。用户选择事故抢占 + 先改方案再批实施。08:54 的 `f283...f039` 不得再当 Wave 0 硬门槛。
|
||||
@@ -0,0 +1,39 @@
|
||||
---
|
||||
title: "pi-native 对比未过 P95 门槛"
|
||||
status: planned
|
||||
created: 2026-09-21
|
||||
updated: 2026-09-21
|
||||
severity: medium
|
||||
---
|
||||
|
||||
# pi-native 对比未过 P95 门槛
|
||||
|
||||
## 现象
|
||||
|
||||
真实 MiniMax-M2.7-highspeed 双后端对比中,`pi-native` 六例全部写出目标文件,容器 `pi-agent` 只有两例文档任务成功。按成功样本计算的 P95 仍是 `pi-native` 16.616s、容器 6.926s,比值为 2.40,超过 1.3 倍替换门槛。因此 dev 默认后端保持 `pi-agent`。
|
||||
|
||||
## 根因分析
|
||||
|
||||
- 时延样本只统计成功且无 P0 的用例。容器 `reasoning` 画像使用 `--no-tools`,不会把助手正文落成目标文件,四例返回 `MISSING_TARGET`,不进入 P95。容器 P95 只由两例较快的文档任务构成。
|
||||
- `pi-native` 的 P95 落在 `doc-outline`(16.616s)。同一提示在容器上是 6.926s。文档任务本身慢于 1.3 倍,不是分位数算法造成的。
|
||||
- 第一轮对比把分位索引截断成 0,两例成功时取了更快的那例,已作废。本结论使用 nearest-rank(`ceil`)后的第二轮日志。
|
||||
|
||||
## 严重度
|
||||
|
||||
`medium`。运行时可以继续在分支上迭代,当前默认链路未切换,容器后端仍可回退。
|
||||
|
||||
## 关联整改
|
||||
|
||||
- 任务:`.doc/ops/short-term/2026-09-21-go-agentx-runtime.md`
|
||||
- 报告:`.doc/test-reports/2026-09-21-go-agentx-runtime-test-report.md`
|
||||
- 后续:缩短 `pi-native` 文档轮次时延,或把门槛改成按同一成功用例配对比较后重新实测。未重新通过前不改 `AGENT_BACKEND`。
|
||||
|
||||
## 证据
|
||||
|
||||
- `.doc/test-reports/assets/go-agentx-runtime/ab-live.txt`
|
||||
- `.doc/test-reports/assets/go-agentx-runtime/ab-live-round1.txt`(作废的截断分位)
|
||||
|
||||
## 开放问题
|
||||
|
||||
- 容器结果不回传 token,本轮容器用量为 0,无法比较 token。
|
||||
- `reasoning` 画像的成功定义是否应要求容器也把正文写入目标文件。当前判定仍按两边各自的 `Result.Success` 与目标文件是否出现。
|
||||
@@ -0,0 +1,156 @@
|
||||
---
|
||||
title: "当前系统模块解耦现状审查"
|
||||
type: docs
|
||||
date: 2026-09-22
|
||||
source_sha: d034aa00e5785f51234b484f9dca6bf4fb037660
|
||||
task_id: modular-contract-standard-2026-09-22
|
||||
---
|
||||
|
||||
# 当前系统模块解耦现状审查
|
||||
|
||||
## 结论与范围
|
||||
|
||||
当前系统属于**已有实质模块化基础,但契约一致性、数据所有权与运行隔离尚未闭合的模块化单体**。不是只有文件夹拆分:已有应用用例、共享事务、PostgreSQL outbox/delivery/inbox、独立 events 进程、PI Runner HTTP typed-result 边界。
|
||||
|
||||
下一步收益最大的工作是统一业务入口、修正事件顺序契约、补运行时校验和资源预算。把现有相互依赖的实现全部包装为 HTTP 服务,会保留语义耦合并引入跨进程失败窗口。
|
||||
|
||||
本报告针对固定源码 SHA,只读检查 Go/React、架构配置、迁移和部署定义。**未检查当前实际镜像/进程/数据库积压,未运行 Go/PG/PI/浏览器或故障注入测试。** 下文“实现存在”是源码证据;“可能造成”是风险推导;不宣称现网事故已复现,也不改变 FEATURE-MATRIX 或发布门禁。
|
||||
|
||||
关联:[通用规范](../system-design/2026-09-22-generic-module-contract-standard.md)、[采用规划](../remediation/2026-09-22-modular-platform-adoption-plan.md)、[任务与验证](../ops/short-term/2026-09-22-modular-contract-standard.md)。
|
||||
|
||||
## 分维度判断
|
||||
|
||||
| 维度 | 已有基础 | 当前局限 | 判断 |
|
||||
|---|---|---|---|
|
||||
| 模块职责 | domain/app/server 分层,组合根 | server 认识大量实现,跨包类型泄漏 | 部分解耦 |
|
||||
| 业务入口 | docflow/stageflow/chatflow 用例 | 对话和 HTTP 同一动作存在旁路 | 需优先收敛 |
|
||||
| 数据边界 | 表 owner 清单与 UoW | 5 项 SQL 写例外、16 项路径例外 | 明确但未闭合 |
|
||||
| 事件通信 | 可靠 PG 投递与独立进程 | 顺序规则与 ADR 冲突,校验不完整 | 机制具备,语义有缺口 |
|
||||
| 并发与幂等 | claim、lease、token、DB 收据 | 慢消费者共享循环,同 ID 异载荷不校验 | 部分保证 |
|
||||
| 跨进程边界 | Web/server、PI Runner、events | 业务模块大多仍共享 server 进程/资源 | 不能宣称全模块故障隔离 |
|
||||
| 前端功能 | API/hooks 拆分 | 根状态和 setter 跨功能共享 | 文件组织优于状态边界 |
|
||||
| 工程约束 | arch-check 与契约 registry | 静态覆盖有限,不证明运行隔离 | 有工具,须明确盲区 |
|
||||
|
||||
不提供无权重依据的“解耦百分比”。以下发现按对数据与行为的实际影响排序,而非按文件大小排序。
|
||||
|
||||
---
|
||||
|
||||
## A1. 事件领取规则与已接受的顺序契约相冲突
|
||||
|
||||
**高优先级源码问题。** ADR 规定允许首个高领域版本 bootstrap,禁止把 MemoryBus 的连续版本等待搬到 PG dispatcher:`.doc/adr/2026-09-15-event-consumer-checkpoint.md:12-23`。
|
||||
|
||||
当前 `internal/events/dispatcher.go:39-46,75-84` 采用 `version <= checkpoint + 1`;无 checkpoint 时只接纳版本 0/1。生产者 `internal/app/docflow/commands.go:182-185` 使用 document record ID,`:211-214` 使用 candidate ID,`:162-165` 使用文档账本版本。这些不是从 1 开始连续的事件序号。
|
||||
|
||||
因此在“无 checkpoint、第一条版本为 42”这一明确条件下,该事件按 SQL 不能被领取。是否已有这种实际积压未查数据库,不能报成现网观测。
|
||||
|
||||
现有 `internal/events/pg_test.go:18-28` 固化同样 gap 规则;`dispatcher_pg_test.go:105-109` 使用 v1/v2,不能覆盖稀疏首事件。
|
||||
|
||||
**建议验收**:真实 PG 下测试首次 v42、v42→v47、部分事件订阅、毒消息隔离;按既有 ADR 恢复 bootstrap,或经明确新 ADR 引入独立事件序列及迁移。通用规范对应 MCS-15。
|
||||
|
||||
## A2. 同一批准动作存在 HTTP 与对话入口分叉
|
||||
|
||||
**高优先级待验证风险。** HTTP `internal/server/handlers.go:793-808` 调用 `docflow.Commands.Approve`,后者在 `internal/app/docflow/commands.go:173-188` 执行 UoW 与 EventApproved。
|
||||
|
||||
对话 `internal/chat/action_executor.go:68-76` 直接调用 GovernanceEngine.ApproverApprove;`internal/app/app.go:294-307` 已不再注册旧通知/批准 hook,`internal/docgov/engine.go:957-960` 的直接路径仅尝试旧 hook。
|
||||
|
||||
源码证明入口路径不同,存在绕过 durable workflow_advance/notify 的风险;本次未执行真实对话批准,不能把完整用户后果记为已复现。
|
||||
|
||||
**建议验收**:同一授权场景分别从 HTTP、对话、后台任务触发,比较授权拒绝、状态提交、事件、工作流推进与通知,所有入口汇入同一用例。通用规范对应 MCS-04。
|
||||
|
||||
## A3. 契约登记尚未成为完整运行时校验
|
||||
|
||||
`internal/events/registry.go:28-52` 登记 producer、consumer、schema、PayloadFields;`:75-91` 主要检查启用与消费者。
|
||||
|
||||
`internal/events/envelope.go:65-85` 检查基础字段、schema、digest/scope,但不按事件逐项校验 producer allowlist、JSON 必填/类型/额外字段。`internal/events/pg.go:32-47` 依赖此验证。`inventory.go:29-63` 也未完成 payload 结构检查。
|
||||
|
||||
实际 `internal/app/docflow/commands.go:279` 的 Producer 为 `docflow`,registry 示例为 `app/docflow`(`registry.go:42-46`),当前路径不会因此拒绝。消费 hydration `dispatcher.go:204-224` 与 handler 调用 `worker.go:252` 也不能证明所有入口统一重新校验。
|
||||
|
||||
**建议验收**:未知事件/schema、伪造 producer、缺必填、异类型、超大 payload、digest/tenant/environment 不符均有发布和消费负例。通用规范对应 MCS-08/09/18/21。
|
||||
|
||||
## A4. 消费者逻辑独立,但资源执行仍串行共享
|
||||
|
||||
`internal/events/worker.go:99-113` 逐一 RunOnce 各消费者;`:137-147` 一批先 claim 再逐个 handle。心跳直到该条 handle 才启动(`:208-234`)。
|
||||
|
||||
慢消费者会延迟同 worker 的其他消费者;预取队尾还可能在开始处理前耗掉 lease。增加副本能缓解吞吐,不证明消费者有独立预算和公平性。当前可隔离永久错误,不等于慢任务也隔离。
|
||||
|
||||
**建议验收**:阻塞一个消费者、保持另一个持续输入,后者满足自己的延迟预算;批量排队超过租期时不允许并发重复副作用。先按空闲槽 claim,并配置每消费者超时、并发、池配额;高风险任务再进程隔离。对应 MCS-14/17。
|
||||
|
||||
## A5. 去重与健康检查不能被扩大解释
|
||||
|
||||
`internal/events/pg.go:43` 对相同 event_id 使用 DO NOTHING,未比较已有 payload digest。因此“重复 ID 被忽略”并不保证“同键异载荷会冲突”。
|
||||
|
||||
`cmd/events/main.go:91-115` 的 health、ready、live 分别关注进程、DB/schema/注册条件、调度心跳;`worker.go:109-112` 在处理前 Touch 且忽略 RunOnce 返回错误。Compose healthcheck 使用 /health(`docker-compose.dev.yml:170-175`)。
|
||||
|
||||
**建议验收**:同 ID 同内容返回既有结果、不同内容冲突;依赖持续失败时最老消息年龄和分消费者失败数告警,不能依靠健康探针证明业务前进。对应 MCS-13/19/20。
|
||||
|
||||
---
|
||||
|
||||
## B1. 组合根、契约类型与实现仍相互渗透
|
||||
|
||||
优点:`internal/app/app.go:96` 集中装配,`internal/server/server.go:87` 接收 runtime。限制:`server.go:40-84` 持有领域具体服务、pool、上下文等,`:123-132` 还回填 Runtime 并初始化执行器。HTTP 适配器获得整个 Runtime,难以维持最小依赖。
|
||||
|
||||
`internal/app/stageflow/usecase.go:10-37` 是窄端口且未配置时 fail closed,但 `types.go:3-15` alias 到 bizdev 模型。`internal/app/chatflow/ports.go:75-106` 返回 ctxmgr/coordinator/projectinstance 具体类型。接口改变了调用位置,仍未彻底隐藏内部模型。
|
||||
|
||||
本次 server 生产 SQL 搜索未发现真实业务 SQL,**不能把持有 pool 等同于已经直接越权写表**。改造重点是缩小可用能力与未来变更影响,不虚构违规。
|
||||
|
||||
## B2. 单写者有登记,仍有明确例外
|
||||
|
||||
`.doc/system-design/module-boundaries.yaml:276-374` 登记表 owner,`:471-511` 登记 5 项 SQL 例外。
|
||||
|
||||
源码确认:`internal/docrevision/pg_store.go:456-477` 更新 freeform_documents/document_records;`internal/docduty/store.go:144`、`revoke.go:154` 修改 document_records;`internal/projectinstance/store.go:920` 更新 task_runs。
|
||||
|
||||
建议通过 owner repository/用例端口逐项归还写权,保留必需事务边界。不得为了删除一个 import,把同一 SQL 移到万能公共 repository。
|
||||
|
||||
## B3. 共享事务值得保留,不能随意替换为网络调用
|
||||
|
||||
`internal/app/docflow/commands.go:88-112` 使用 UoW 与 owner GetForUpdate;`internal/docrevision/pg_store.go:482-491` 加入同一事务;`internal/app/uow/pg_uow.go:52-80,95-124` 提供有界事务重试、锁等待和提交。
|
||||
|
||||
`internal/app/app.go:269-275` 接入 events.PGSink,`internal/events/pg.go:17-58` 拒绝无 UoW 发布并同事务创建 envelope/delivery。这是实质强一致性能力。若以后拆进程,必须重新定义跨域中间态、补偿和对账,不能用分布式锁替代事务。
|
||||
|
||||
## B4. 文件与前端状态也构成模块间隐式协议
|
||||
|
||||
文件证据:`internal/coordinator/context.go:456-459` 读取 output.md;`engine.go:691-701,895,1051` 读写/拼接共享产物路径;`internal/docgov/lease.go:415-416` 写 projection 文件。文件 owner、不可变引用、版本与发布原子性应与数据库同样治理。
|
||||
|
||||
前端证据:`web/src/App.tsx:130-170,1163-1204,1367-1406` 将消息、交付物、缓存及 setter 传给多个功能 hooks;`useSendMessage.ts:85-121` 可修改多个域状态。建议 owner 管理状态、对外命令/查询/事件;浏览器内无需强制 HTTP。
|
||||
|
||||
`web/src/api/authHeaders.ts:27-44` 已有认证辅助,但 chatStream、taskRuns、docgov 等仍各自 fetch。统一 client 应处理通用超时、错误、取消与身份,功能 DTO 继续分域。
|
||||
|
||||
## B5. 静态架构检查有价值,但证明范围有限
|
||||
|
||||
`internal/archtest/scan.go:38-70` 默认只扫 internal 生产 Go;`:169-205` 检查 import allowlist 和登记表的 SQL 字符串。它不涵盖前端、默认 cmd 范围、动态 SQL 完整语义、实际权限、兼容性和资源隔离。
|
||||
|
||||
`scan.go:18,392-410` 的事件匹配范围主要为 document.* / intent.plan.* 和特定调用模式,不能根据 YAML 中存在 taskrun/fav 就假定每条协议都被检查。
|
||||
|
||||
`module-boundaries.yaml:182-225` 仍允许 server 依赖大量领域;`:641-651` 登记 sql_write=5、path=16 基线。**这是读取到的配置,不是本次 arch-check 执行结果。**
|
||||
|
||||
---
|
||||
|
||||
## 可保留的隔离与演进能力
|
||||
|
||||
- 独立 worker:`cmd/events/main.go:68-89,127-130` 注册 notify/advance/projection,FAV 明确不注册;Compose 已有 events 服务。历史“没有独立 worker”的判断已过时。
|
||||
- 领取与确认:`dispatcher.go:49-97,163-200,227-259` 有原子 claim、owner/token、attempt、inbox/checkpoint;旧 ClaimIDs 已禁用。
|
||||
- DB 效果原子性:`worker.go:247-275` 的 handler、fenced ack、commit 同事务;仅适用于参与同一 DB 事务的效果,不能扩展为任意外部 IO。
|
||||
- 消费者实现:`internal/app/docproject/consumer.go:73-94` 使用事件回执与 no-replace;`docadvance/consumer.go:80-104` 使用同事务推进与通知。
|
||||
- 冻结执行输入:`internal/workflow/runtime/orchestrator.go:27-41,69-85` 从冻结实例取职责,缺失时拒绝,可泛化为任务绑定配置/契约版本。
|
||||
- PI Runner:`internal/agent/piagent.go:145-194` 有 HTTP/Bearer、超时、run_id、typed result 和大小限制;`remote_result.go:63-79` 对存在但非法 typed 字段 fail closed。
|
||||
|
||||
## 测试证据边界
|
||||
|
||||
以下是已有测试定义,不是本次 PASS:
|
||||
|
||||
| 路径 | 已有测试意图 | 本次状态 |
|
||||
|---|---|---|
|
||||
| internal/app/docflow/same_tx_pg_test.go | 状态与 outbox 同事务回滚 | 未运行 |
|
||||
| internal/events/dispatcher_pg_test.go | 多 worker、off/shadow、ack、隔离 | 未运行 |
|
||||
| internal/app/docnotify/e1a_pg_test.go | 通知权限、shadow/live、回滚 | 未运行 |
|
||||
| internal/app/docadvance/e1b_pg_test.go | 工作流事件消费 | 未运行 |
|
||||
| internal/app/docproject/e1c_pg_test.go | 投影与 no-replace | 未运行 |
|
||||
| internal/agent/piagent_typed_e2e_test.go | 条件启用的真实 PI | 未运行 |
|
||||
|
||||
PG 测试在 short 或缺少独立 DSN 时可跳过;PI 测试有显式开启条件。建议新增 A1–A5 的针对性场景,再做受影响用户入口验收。未经授权,本次不启动这些实现或共享环境测试。
|
||||
|
||||
## 与原方案的关系
|
||||
|
||||
继续引用 2026-09-20 A–G 分批整改作为现有依赖收敛清单,不能据此宣称原批次已经完成。A1–A5 是本次新增或细化的源码证据,实施时应并入同一治理链,避免开第二套互相冲突的解耦项目。
|
||||
|
||||
原规范保留模块化单体,本次通用规范允许按条件选择进程/服务隔离。两者分别用于“当前项目生效规则”和“未来项目待采纳标准”,没有自动覆盖关系。
|
||||
@@ -0,0 +1,27 @@
|
||||
# 历史问题补录:可选职责与正文哈希
|
||||
|
||||
补录日期:2026-09-23;owner:Codex;登记任务:[issue-learning-2026-09-23](../ops/short-term/2026-09-23-issue-learning.md)。这是两个问题的登记主记录,原审计、修复任务及验收报告继续作为事实证据;没有重新运行产品测试或读取业务数据。`evidence_basis=historical`,当前运行状态未复测,源码复核基线为 `2fdb6e548e3784771f27e6a9e79b9c364f76c566`。
|
||||
|
||||
## nullable-duty
|
||||
|
||||
- issue_id:`ISSUE-20260923-nullable-duty`;issue_state:`resolved`;severity:high;recurrence_count:0(指登记后重开次数,非历史发生总数)。
|
||||
- 发现/修复日期:2026-09-17;原处理 owner:Cursor;补录 owner:Codex;原任务:`fix/docgov-optional-duty-null-fk`。
|
||||
- 现象与已证实根因:[原审计](2026-09-17-docgov-optional-duty-null-fk.md)。可选 reviewer 缺席合法返回 0,但创建路径直接写入可空 FK;heal 路径已有空值映射,创建路径漏改。底层 FK 又被错误分型掩盖。
|
||||
- 同类范围:可选职责的创建/heal 写入边界。历史报告验证 reviewer/approver 为 NULL;不能由此推断所有 FK、全职责模式和全部授权边界均已验证。
|
||||
- 修复思路:保留可选职责语义,在 SQL 边界将缺席值映射 NULL,并改善错误分型;通过强制配置 reviewer 绕过错误会改变业务契约。未发现其他尝试的实测记录,不虚构失败实验。
|
||||
- 修复经过/提交:[原任务](../archive/ops/2026-09-17-docgov-optional-duty-null-fk.md),历史合并 `e488d10`;本次只核对原文记录,不把短 SHA 当当前制品身份。
|
||||
- 验证与关闭范围:[原报告](../test-reports/2026-09-17-docgov-optional-duty-null-fk-test-report.md) 记录单测、PG 集成、真实任务 API 启动与 DB NULL;证明账本创建通过,不证明真实 UI 或 PI 全流程完成。历史 deployment=passed(dev,来源为原报告),当前运行未复测。
|
||||
- 本次复核:当前源码 `internal/docgov/engine.go` 创建路径仍调用 `nullIfZero`;这是源码检查,未重跑 PG。
|
||||
- 经验:[LESSON-20260923-nullable-duty](../ops/lessons/2026-09-23-nullable-duty.md)。后续触发:职责模型或任一持久化入口变化时复核,异常复发重开。独立的 flushSync 警告不在本条关闭范围。
|
||||
|
||||
## content-hash
|
||||
|
||||
- issue_id:`ISSUE-20260923-content-hash`;issue_state:`resolved`;severity:critical;recurrence_count:0(登记后)。
|
||||
- 发现/修复日期:2026-09-14;原处理:Cursor 修复、Antigravity UI 验收;补录 owner:Codex。
|
||||
- 现象与因果链:[原审计](2026-09-14-project143-controlled-content-404.md)。文件存在却被报 404;规范化去掉有硬换行语义的双空格,bootstrap 只改账本哈希未同步文件;并发 hydration 与无效轮询更新放大故障。
|
||||
- 同类范围:旧文档 bootstrap、规范化、账本/文件投影、错误映射与刷新竞态。历史扫描范围见原审计,不扩大为所有数据无问题。
|
||||
- 修复思路/选择:[整改方案](../remediation/2026-09-14-controlled-content-canonical-hash-remediation.md)。保持文本语义、原子投影和结构化错误;历史原文件与旧 head 先保全再显式 migration_repair。静默覆盖原文件会丢失语义,不能用于“对齐哈希”。这不是本轮数据操作授权。
|
||||
- 修复经过:[原审计关闭结果](2026-09-14-project143-controlled-content-404.md#关闭结果) 与 [最终报告](../test-reports/2026-09-14-controlled-content-ui-acceptance.md);后续水合/缓存修复合入 `d0e8f60`、`36e4bc3`。报告保留早期失败及无效运行,只有 clean-run3 / full-chain-final 属最终有效证据。
|
||||
- 验证与关闭范围:原报告记录旧项目真实页面、全链路主阶段和重启恢复 PASS;历史 deployment=passed(dev)。不据此宣告当前 production_ready 或当前制品无回归。
|
||||
- 本次复核:`internal/docrevision/canonicalize.go` 已委托 doccontent;`canonicalize_golden_test.go` 包含硬换行和封装一致性测试。本次未执行这些测试。
|
||||
- 经验:[LESSON-20260923-content-hash](../ops/lessons/2026-09-23-content-hash.md)。后续触发:canonicalizer、bootstrap、投影或水合修改时复核;复发追加时间线并重开。
|
||||
@@ -0,0 +1,55 @@
|
||||
---
|
||||
issue_id: ISSUE-20260923-matrix-status-regression
|
||||
issue_state: resolved
|
||||
severity: high
|
||||
owner: Cursor
|
||||
task_ids: [module-batches-ag-status-fix-2026-09-23]
|
||||
created: 2026-09-23
|
||||
occurred_at: 2026-09-23
|
||||
updated: 2026-09-23
|
||||
recurrence_count: 0
|
||||
evidence_basis: current
|
||||
lesson_ids: [LESSON-20260923-matrix-status-cas]
|
||||
---
|
||||
|
||||
# FEATURE-MATRIX 状态字段被合并冲突回退
|
||||
|
||||
按 [闭环规范](../ops/2026-09-23-issue-learning-workflow.md) 维护。关联任务:[module-batches-ag-status-fix](../ops/short-term/2026-09-23-module-batches-ag-status-fix.md)。
|
||||
|
||||
## 事实与证据
|
||||
|
||||
- **预期**:`module-batches-ag` 在 A–G 合入且 arch-check 全 0 后保持 `done`(提交 `77bdbdbc` 已写入)。
|
||||
- **实际**:本地 `dev` tip 上该行状态为 `planned`,剩余工作栏仍写「关闭本伞行」与 A–G 已合入事实矛盾;用户观感为「多次要求实现但未实现」。
|
||||
- **触发**:含 FEATURE-MATRIX 的 closeout / sync 合并冲突手解,取了无 `record_id` 或旧侧行内容。
|
||||
- **影响**:后续会话按 `planned` 错误前提规划,可能重复实施或延误收口;不构成发布 blocker(发布关系仍为 `non_blocker`)。
|
||||
- **环境**:本机 `dev` @ `18b9556f`(任务基线);修复提交见本任务 feature 分支。
|
||||
- **复现(修复前)**:`git show 77bdbdbc:.doc/status/FEATURE-MATRIX.md` 该行 status=`done`;修复前 tip 同行为 `planned`。
|
||||
|
||||
## 根因与同类范围
|
||||
|
||||
- **已证实**:共享文档在 `docs apply` 行级 CAS / `record_id` 稳定键启用前窗口内,merge 冲突对手解无机器核验状态字段;手解取旧侧覆盖 `done`。
|
||||
- **已排除**:A–G 代码未合入(合入 merge commits 与 arch-check PASS 否定)。
|
||||
- **共用机制**:CURRENT / FEATURE-MATRIX 等协调 SSOT;任何绕过 `docs apply` 的整表手改或冲突取旧侧。
|
||||
- **同类入口**:其他矩阵行、CURRENT 认领行在无 CAS 收据时同样脆弱;本轮只修 `module-batches-ag`,不扩大扫全表 unless 另授权。
|
||||
|
||||
## 修复思路与过程
|
||||
|
||||
| 日期 | 假设 / 尝试 / 动作 | 实际结果与证据 | 决策 / 下一步 / owner |
|
||||
|---|---|---|---|
|
||||
| 2026-09-23 | 只读考古 git + arch-check | A–G 已落地;状态回退成立 | 按计划修正登记,不重做代码 / Cursor |
|
||||
| 2026-09-23 | docs apply 行级 CAS 恢复 `done` + 登记 lesson | MATRIX 行 status=`done`;header 同步;arch-check PASS | resolved;合入 local_dev / Cursor |
|
||||
|
||||
方案:恢复矩阵事实状态;登记问题与经验;强制后续矩阵变更走 `docs apply`;合入含 MATRIX 的合并后机器核对目标 `record_id` 状态列。
|
||||
|
||||
## 验收与关闭
|
||||
|
||||
- 原例:PASS — MATRIX `module-batches-ag` status=`done`(docs apply 收据 + commit `b9d09c97`)。
|
||||
- 同类:本任务不批量改其他行;风险已记入 lesson。
|
||||
- 正常:PASS — `docs apply` 无拒绝;`./scripts/arch-check.sh --mode block` PASS(worktree tip)。
|
||||
- deployment:`not_required`(纯文档)。
|
||||
- resolved:2026-09-23;范围=状态登记与台账,不含 Server 镜像字段增量。
|
||||
|
||||
## 经验与复发
|
||||
|
||||
- lesson:[LESSON-20260923-matrix-status-cas](../ops/lessons/2026-09-23-matrix-status-cas.md)
|
||||
- 防护:能力完成升 `done` 已有 `docs:approve` + evidence `cat-file` 门禁;复发时重开本 issue 并检查是否绕过 apply。
|
||||
@@ -0,0 +1,67 @@
|
||||
# 管理员重置密码 / 登录凭据缺陷 — 问题主记录
|
||||
|
||||
更新:2026-09-24。任务:`admin-password-reset-2026-09-24`。
|
||||
|
||||
## ISSUE-20260924-admin-reset-dead
|
||||
|
||||
### 问题
|
||||
|
||||
管理台「重置密码」按钮调用 `authClient.adminResetPassword`,客户端硬 `throw`,后端无 `reset-password` 路由;UI 仍硬编码 `ResetPass123` 暗示成功。验收脚本曾重置 `chenwei` 哈希且不披露口令后,管理员无法通过 UI 恢复访问。
|
||||
|
||||
### 根因
|
||||
|
||||
T20-F4 已设计未实施(选项 B 卡产品)。`password_changed_at` 停在 2026-09-20 证明重置从未入库。
|
||||
|
||||
### 修复
|
||||
|
||||
`POST /api/v1/admin/users/{id}/reset-password`:服务端随机临时口令、`must_change_password=true`、撤销会话、审计表 `user_password_reset_audits`(goose 00067);前端接线并去掉硬编码。
|
||||
|
||||
### 状态
|
||||
|
||||
resolved(本任务合入后)。
|
||||
|
||||
---
|
||||
|
||||
## ISSUE-20260924-login-error-envelope
|
||||
|
||||
### 问题
|
||||
|
||||
登录失败响应 `code=AUTHZ` / `message=无权访问`,前端再把整段 JSON 原文塞进 `Error.message`,用户误判为权限问题。
|
||||
|
||||
### 根因
|
||||
|
||||
`httpx.CodeFromStatus(401)=AUTHZ` + `SafeMessage`;`auth.ts` login 未用信封解析、未优先 `error` 领域字段。
|
||||
|
||||
### 修复
|
||||
|
||||
`authErrorMessage` 优先取信封 `error`;不改全局 AUTHZ 映射(事件复用与安全取舍另立专项)。
|
||||
|
||||
### 状态
|
||||
|
||||
resolved。
|
||||
|
||||
---
|
||||
|
||||
## ISSUE-20260924-zombie-credentials
|
||||
|
||||
### 问题
|
||||
|
||||
`CreateUser` 在 `PasswordHash==""` 时静默跳过 `user_credentials` 插入;`LEFT JOIN` + `COALESCE` 使登录哈希为空串,任意密码均失败且报错与真凭据错误相同。
|
||||
|
||||
### 盘点(只读,2026-09-24)
|
||||
|
||||
| 环境 | total | missing_cred | empty_username |
|
||||
|---|---|---|---|
|
||||
| dev | 416 | 263 | 255 |
|
||||
| test | 9 | 0 | 0 |
|
||||
| main | 4 | 3 | 0 |
|
||||
|
||||
main 三行为 goose 00011 seed(`seed-admin` 等),非业务用户。本任务**不清理**存量;仅 fail-closed 防新增。
|
||||
|
||||
### 修复
|
||||
|
||||
PgStore/MemoryStore `CreateUser` 拒绝空哈希;`Login` 对空哈希记 `slog.Warn(user_id)` 仍统一 401。
|
||||
|
||||
### 状态
|
||||
|
||||
resolved(机制);存量清理 = open / 另授权。
|
||||
@@ -0,0 +1,49 @@
|
||||
---
|
||||
issue_id: ISSUE-20260924-cursor-hook-event-contract
|
||||
issue_state: open
|
||||
severity: medium
|
||||
owner: Cursor
|
||||
task_ids: [cursor-governance-hooks-2026-09-24]
|
||||
created: 2026-09-24
|
||||
occurred_at: 2026-09-24
|
||||
updated: 2026-09-24
|
||||
recurrence_count: 0
|
||||
evidence_basis: current
|
||||
lesson_ids: [LESSON-20260924-cursor-hook-advisory-gates]
|
||||
---
|
||||
|
||||
# Cursor hook 事件字段契约未文档化
|
||||
|
||||
## 事实与证据
|
||||
|
||||
预期:`beforeMCPExecution` / `sessionStart` / `stop` 的 stdin 字段名与 matcher 匹配串在官方文档中明确,便于 failClosed 硬门禁。
|
||||
实际:官方 create-hook skill 仅明确 `beforeShellExecution` 的 `command` 字段;`beforeMCPExecution` 不支持 `updated_input`;`sessionStart` 无文档化返回字段可注入上下文;`MCP: ...` matcher 形式只写给 `preToolUse` 族。实现层字符串探测存在 `mcp_server_name`/`tool_name`/`tool_input`,但非文档契约。
|
||||
|
||||
证据:本任务调研记录;单元测试用多名容错驱动;真实 Cursor IDE 事件采样待 `CURSOR_HOOKS_PROBE=1`。
|
||||
|
||||
## 根因与同类范围
|
||||
|
||||
客户端 hook API 文档滞后于实现。同类:任何依赖未文档化 hook 输入的 failClosed 门禁都有假阴性/假阳性风险。
|
||||
|
||||
## 修复思路与过程
|
||||
|
||||
| 日期 | 动作 | 结果 | 下一步 |
|
||||
|---|---|---|---|
|
||||
| 2026-09-24 | 落地 advisory hooks + 多名容错 + probe 开关;异形 fail-open | 单元回归 PASS | 用户触发真实 MCP/shell 事件采样后收紧 |
|
||||
|
||||
## 验收与关闭
|
||||
|
||||
- 静态/单元:已覆盖(见测试报告)
|
||||
- 实机:打开 `CURSOR_HOOKS_PROBE=1`,触发一次 `pi_subagent_roles` 与一次 shell,归档 `.cursor/hook-probe.jsonl` 片段到测试报告 assets;确认字段名后可将 matcher/`failClosed` 收紧并将本 issue → verifying/resolved
|
||||
|
||||
## 经验与复发
|
||||
|
||||
见 [LESSON-20260924-cursor-hook-advisory-gates](../ops/lessons/2026-09-24-cursor-hook-advisory-gates.md)。
|
||||
|
||||
## 2026-09-24 IDE 采样更新
|
||||
|
||||
- `postToolUse` 审计:`tool_name` / 审计字段为 `MCP:pi_subagent_roles`(带 `MCP:` 前缀)。
|
||||
- 修复:`_lib.normalize_tool_name` 剥前缀;回归 `test_ask_mcp_prefixed_tool_name_bad_sha`。
|
||||
- `pi_subagent_roles` IDE MCP 调用 PASS;`postToolUse` 收据 checklist 已注入。
|
||||
- `beforeMCPExecution` 完整 stdin 仍缺(Cursor 进程未设 `CURSOR_HOOKS_PROBE=1`);issue 保持 verifying。
|
||||
- `agentctl`/`jev` 未出现在 IDE MCP 缓存目录;进程可手动 stdio 启动;与路径修复独立,另记。
|
||||
@@ -0,0 +1,37 @@
|
||||
# ISSUE-20260924-non-author-400-duty
|
||||
|
||||
## 摘要
|
||||
|
||||
非编制项目成员无法上传/总结/对话写草稿;权限错误经 `writeDocGovError` 默认落成 HTTP **400**。
|
||||
|
||||
## 根因
|
||||
|
||||
1. `domainHTTPStatus` 未映射 `ErrOnlyAuthorCanEdit` / `ErrReviewerCannotEdit` / `ErrApproverCannotEdit` → 403。
|
||||
2. `classifyAccess` / `AllowedTaskKeys` / `CanEditDocumentContent` 将 run/edit 绑编制职责(三道门协同过宽)。
|
||||
3. 前端写意图路由偶发把「总结+写动词」送入 task run。
|
||||
|
||||
## 处置(deny_only_submit)
|
||||
|
||||
- run/edit → 项目成员级;submit/review/approve 保留职责门禁。
|
||||
- AuthorID 仍归编制职责人(`docduty.Resolve` 不变)。
|
||||
- 人工编辑传 `ActorIsMember`,不复用 `RoleSystem`。
|
||||
|
||||
## 验证
|
||||
|
||||
见 [测试报告](../test-reports/2026-09-24-non-author-member-access-test-report.md);真实 PI PASS。
|
||||
|
||||
## 状态
|
||||
|
||||
resolved(2026-09-24)
|
||||
|
||||
## 五态收口(2026-09-24)
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| review_state | accepted(真实 PI `TestNonAuthorMember_PiAgent_RunEditSubmitGates` PASS;工程门禁 PASS) |
|
||||
| integration_state | merged_local_dev(`dev@e98e2d71`;feature tip `8b2621a4` 为祖先) |
|
||||
| deployment | not_required(本轮未要求加载 launchd 业务制品) |
|
||||
| cleanup | pending(`.worktrees/non-author-member-access-2026-09-24` 与 integrate 现场待独立维护者复查后清理;禁止 `--force`) |
|
||||
| remote_sync | pushed(`origin/dev` = `e98e2d71`,`./scripts/git-push-dev.sh dev` 已成功) |
|
||||
|
||||
相关 agentctl 任务:`non-author-member-access-2026-09-24`、`non-author-member-access-docs-2026-09-24`、`integrate-non-author-docs-2026-09-24` 均为 `done`。
|
||||
@@ -0,0 +1,45 @@
|
||||
# PI Subagent 执行器初版边界审查
|
||||
|
||||
task_id:subagent-workflow-standard-2026-09-24;issue_id:ISSUE-20260924-pi-executor-boundaries。
|
||||
owner:Cursor(修复)/ Codex(复核);issue_state:resolved;severity:high。
|
||||
本记录针对尚未发布的执行器初版,不表示 dev 或产品 Runner 存在这些实现。
|
||||
|
||||
## 事实与机制
|
||||
|
||||
1. 独立验证发现 PI 内置工具的路径规范化与扩展守卫不一致。安装版本 0.85.1 的 tools/path-utils.js 中 resolveToCwd 使用 stripAtPrefix 并展开 home;初版守卫使用 path.resolve(root,input)。
|
||||
2. 以专门创建的 /tmp/pi-guard-audit-* 临时目录及 outside.txt 假文件测试 @绝对路径,实际结果为 guard_blocked=false、actual_tool_path_escapes=true。没有读取真实密钥或业务文件。
|
||||
3. 同类范围:@ 前缀、~ 前缀、相对父路径、符号链接、Unicode/读取路径规范化;MCP 的同仓/工作区验证和临时文件写入;报告幂等与损坏收据;进程树/输出上限/环境变量隔离。
|
||||
4. 初版静态阅读另发现:跨仓 MCP 可能执行目标仓脚本;输出仅在 communicate 完成后截断;只回收仍存活 leader 的进程组;测试环境黑名单不足;模型报告用关键词推导 PASS。上述需要实现修复和负例,不以本行代替实测。
|
||||
5. 初版测试夹具存在 eager stderr.read(),在 MCP 仍存活时阻塞。host 两次仅终止 /tmp/pi-subagent-test-* 的假 MCP 子进程以释放测试,未终止产品或用户进程。
|
||||
|
||||
## 复现与迭代
|
||||
|
||||
- 初次 RED:19 项,7 failures / 11 errors,主实现未创建;存在性/调用失败为已缺失功能,不当作实现通过。
|
||||
- 初版回归:19 项,4 failures / 7 errors;耗时含夹具死锁处理。后续错误数不作为发布质量结论,待主机完整重跑。
|
||||
- Cursor 首轮 supervisor 已由 host 为明确的修复交接发送 TERM,退出143;源文件保留。没有未知写副作用后盲目重派,第二轮是带具体修复清单的新执行。
|
||||
- 本机 Qwen3.8-Flash、GLM-5.3-Flash 无工具短请求连通通过,实际 provider/model 与配置一致,正常 stop + agent_end/agent_settled。仅连接证据。
|
||||
- GLM-5.3 对初版整包快照的只读审查 300 秒超时,无完整结论;不报审查 PASS。进程由 subprocess 超时处理结束,未授予工具,无仓库写入。
|
||||
|
||||
## 修复与验收要求
|
||||
|
||||
Cursor 修复清单已交接:统一/拒绝路径规范化;MCP 同仓注册验证和无租约写入;有界双向进程通信/整体回收;测试环境白名单;严格请求/配置与冻结 SHA;损坏收据禁止重派;报告完成与审查通过分离;最终事件完整性;禁用 PI 隐式重试;相关真实 Git/进程/MCP 回归。
|
||||
|
||||
关闭条件:静态发现均落实对应修复或有证据排除;原例与同类负例通过;真实 PI 调用经新执行器完成;审查与测试报告保存。修复中,不新增 validated 经验;验证后再总结。
|
||||
|
||||
## 2026-09-24 修复关闭
|
||||
|
||||
issue_state=resolved 仅针对未发布初版的约定缺陷;代码提交 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119,主机完整工程回归 173 项通过,提交后专项 34 项通过;最终 Cursor CLI→MCP→PI 中 ls/read 全通过。实际覆盖、早期失败和独立 GLM 审查边界见[报告](../test-reports/2026-09-24-pi-executor-test-report.md)。
|
||||
新增[经验](../ops/lessons/2026-09-24-pi-tool-boundaries.md)。本文件前面的“修复中/待验证”为初版历史,当前结论以本节为准。dev 集成/客户端 IDE 验收不由本问题关闭状态推导。
|
||||
|
||||
## cursor-cli-mcp-path
|
||||
|
||||
issue_id:ISSUE-20260924-cursor-cli-mcp-path;issue_state:deferred;severity:medium;owner:工程维护;日期:2026-09-24。
|
||||
本机 Cursor CLI 2026.09.18 在项目 MCP args 中未展开 workspaceFolder 变量,原样传给 Node。pi-subagents 新入口已改工作区相对路径并实测通过。
|
||||
同类只读检查:agent mcp list 也显示既有 agentctl / jev Connection failed,它们仍使用相同变量写法;codegraph ready。未进一步修改/验收这两个既有服务,也未断言 IDE 同样失败。官方支持声明与本机观测须分开。
|
||||
此残差不阻塞 PI MCP(其内部直接调用主仓治理 CLI),不构成本轮产品发布结论;后续由工程维护在 Cursor CLI 升级或这两项 MCP 接入验收时检查路径/stdio 协议,形成独立修复与实际客户端证据。仅保留问题,不宣称已修复。
|
||||
|
||||
|
||||
## cursor-cli-mcp-path 续:NDJSON 回包
|
||||
|
||||
2026-09-24 IDE:`pi-subagents`/`codegraph` ready;`agentctl`/`jev` 不在 MCP 缓存。
|
||||
根因补充:后两者 `send()` 使用 `Content-Length` 帧,而可加载的 `pi-subagents` 使用换行分隔 JSON-RPC。已改为 NDJSON 回包并补 `"type":"stdio"`;仍接受 Content-Length 请求。单元:`scripts/tests/test_mcp_ndjson_framing.py`。IDE 重载后需再核 `list-tools`。
|
||||
@@ -0,0 +1,111 @@
|
||||
# Cursor Auto 与 Subagent 工作流研究及文档验证报告
|
||||
|
||||
日期:2026-09-24;owner:Codex;task_id:subagent-workflow-standard-2026-09-24。
|
||||
范围:现行规范、Cursor 项目配置及官方文档;交付[规范草案](../ops/2026-09-24-subagent-workflow-standard.md)。未运行 Cursor 对话/真实 subagent,未修改产品或运行环境。
|
||||
|
||||
## 1. 研究结论
|
||||
|
||||
推荐主 Agent 协调、按需委派、独立审查与验证的流程。用户提出的八步可作为起点,但需在开始明确授权/验收标准,在方案阶段设计测试,在实施中自测,合并后核对实际运行结果,最后归档和清理。
|
||||
|
||||
| 方案 | 收益 | 代价/缺陷 | 结论 |
|
||||
|---|---|---|---|
|
||||
| 单 Agent 顺序完成全部阶段 | 简单、额外上下文成本低 | 实施者自审容易沿用错误假设 | 适合小型文档/研究;代码交付补独立审查 |
|
||||
| 每阶段固定一个 Agent / 固定模型 | 阶段职责直观 | 无效启动和文档重复;固定模型背离 Auto;阶段间易丢授权/版本 | 不采用 |
|
||||
| 主 Agent + 按需 analyst/reviewer/verifier | 保留上下文入口,独立检查,成本可控 | 需可靠派发包、证据接收和异常恢复 | 推荐;实现并行按风险逐步启用 |
|
||||
|
||||
这是本项目基于现状的设计判断,不是 Cursor 平台保证。
|
||||
|
||||
## 2. 官方能力与推论
|
||||
|
||||
查阅日期为 2026-09-24。在线文档会变化,客户端接入必须另验;不采用社区传闻作为技术契约。
|
||||
|
||||
| 来源 | 查证事实 | 对本规范的影响 |
|
||||
|---|---|---|
|
||||
| [Cursor Subagents](https://cursor.com/docs/subagents) | 自定义角色可位于 .cursor/agents;model 默认 inherit;readonly 与后台字段可配置;子上下文需要主 Agent 提供输入;默认共享 checkout | 采用继承策略、显式交接、仓库管理的写隔离;只读报告由主 Agent 保存 |
|
||||
| [Cursor Models & Pricing](https://cursor.com/docs/models-and-pricing) | Auto 是平台模型路由选项,公开文档列有不同优化模式 | 规则不绑定模型、价格或固定路由;按实际 UI/账户能力记录 |
|
||||
| [Cursor Rules](https://cursor.com/docs/rules) | 支持 AGENTS.md 和项目规则 .mdc | 根入口/客户端入口只指向单一规范,避免重复规则漂移 |
|
||||
|
||||
推论与限制:inherit 能表达继承意图,不足以证明实际模型身份或所有 Auto 请求的路由;独立上下文不保证跨模型独立性;只读权限与运行测试的写产物需要区别处理。Auto 可用性、角色加载、权限、真实派发及费用均未在本会话实测,不保证任何套餐或所有版本可用。云执行不在本次授权与建议默认范围内。
|
||||
|
||||
## 3. 当前仓库证据
|
||||
|
||||
检查基线:dev = 5423b261f97f371bdf7fa5066e9305f9eddaef42;本地 origin/dev 跟踪引用比较为 ahead 74 / behind 0。未 fetch,不能据此声明服务器当前引用。
|
||||
|
||||
- AGENTS / PROJECT:已定义授权分级、任务 worktree、独立状态、业务实施和研究边界。
|
||||
- worktree 操作规范:已有 agentctl 租约、候选验证/合入、共享环境持锁、清理负例和收口要求。
|
||||
- 验证契约:依据变更范围取并集,要求真实用户流程与持久证据;文档变更不要求产品回归。
|
||||
- 文档地图/任务模板:已有最小文档原则,可以按阶段留证而不制造九份重复文档。
|
||||
- .cursor/rules:已有 agentctl、文档、Git 和测试入口。rg --files .cursor 未发现项目 .cursor/agents 角色定义;不推断用户全局目录没有角色。
|
||||
- .cursor/hooks.json:存在 beforeShellExecution 的 Git 守卫;未见本流程阶段完整性校验。此处仅配置阅读,没有实际触发 hook。
|
||||
- cursor --version:3.21.16 / 8ae78e8eee1e63479c7e0504b664bc0a80c68000 / x64;agent --version:2026.09.18-9a7762b。CLI 版本不代表 IDE 当前会话配置已验收。
|
||||
- agentctl status:当前配置 policy_revision 为 agent-governance-2026-09-23-fav-constraint-restored;存在其他任务持 env:dev。研究不使用该环境,不改他人任务。
|
||||
|
||||
已读规范修订与工具配置 revision 不同,记录两者分别是什么,不把一个全局字段视作所有 Markdown 修订版本。
|
||||
|
||||
## 4. ISSUE-20260924-cursor-test-rule-drift
|
||||
|
||||
issue_state:open;严重度:medium;owner:Codex(研究);evidence_basis:本次源码/配置阅读;产品影响未复现。
|
||||
预期:客户端测试规则只引用验证契约,由适用范围和批准环境决定套件/Runner。
|
||||
实际:.cursor/rules/test-reports-standard.mdc(alwaysApply=true)仍要求报告附全量 go test -v ./...,固定 MiniMax-M2.7-highspeed,并指向已不存在的 PROJECT §8。与验证契约中的范围选择、实际批准模型、普通小任务记录方式不一致。
|
||||
|
||||
已证实机制:客户端复制完整测试规则形成第二份来源,主规范修订后副本继续陈旧。未证实:实际 Cursor 是否因此执行了错误模型/测试、费用或运行行为是否受影响。
|
||||
为何已有保护不足:静态读取显示没有针对该副本文案与验证契约的一致性证据;本次没有运行 hook/CI,不能断言所有自动防护都缺失。
|
||||
同类检查范围:.cursor/rules 下五个规则文件及 hooks 配置、根 AGENTS/PROJECT、验证契约、规范登记、任务/收口模板。其余四个 mdc 主要转发入口;本次未检查所有其他客户端和全局规则。
|
||||
|
||||
推荐修复:将该 mdc 缩为验证契约与报告路径指针;结构要求归并现有权威文件,避免再复制模型与全量命令。不是改产品 Runner 模型或删除必要验证。
|
||||
验收:规则文本无固定模型/无条件全量测试/失效章节;文档任务、Go 任务、产品 PI 任务分别映射到既有验证矩阵;Cursor 实际读取入口并正确选择验证层级。静态修复与实机行为分别报告。
|
||||
时间线:2026-09-24 发现并登记;本次仅提出修复,未实施,issue 保持 open。无新 validated lesson;未验证修复不包装成经验。
|
||||
|
||||
## 5. 风险和关键设计
|
||||
|
||||
- 阶段和角色不是一对一关系:固定九名 Agent 会增加交接成本;初期三角色足够,主 Agent 可实施。
|
||||
- 只读 reviewer 无法自行写审查文件:主 Agent 转存并保留作者/ID,避免“要求只读同时要求落盘”的矛盾。
|
||||
- verifier 运行构建/测试会写缓存、数据甚至环境:单独授权,持对应租约,不能装作普通只读检查。
|
||||
- 子 Agent 默认共享目录:采用单写者;并行写另建登记 worktree,主会话的自动隔离配置不替代仓库门禁。
|
||||
- 审查和测试必须绑定版本:修复后重审受影响范围;候选变化重验;运行制品与报告提交分开。
|
||||
- 清理在验收后:唯一日志/截图先归档,owner 退出后由维护者复查,不主动删除当前使用的工作区。
|
||||
- 人工确认默认在可审方案形成后;已有端到端授权则沿用。用户未回复偏好,本草案采用该可调整默认,不把沉默当批准。
|
||||
- 模型路由和自动审批不同:Auto 不扩大业务或环境权限,普通 Cursor 不套用 Herdr 固定模型。
|
||||
- 阶段规范为 manual;文档审核通过不等于自动执行系统已实现。
|
||||
|
||||
## 6. 文档验收与未运行项
|
||||
|
||||
本次仅文档研究。静态检查结果在任务“验证与证据”节记录;检查对象为本次全部变更文件内容。
|
||||
情景自审覆盖:研究-only、简单文档、标准功能、修复回环、并行冲突、readonly 转存、子任务未知、候选变化、验收失败、清理拒绝、上下文恢复。该项是文档推演,不能作为运行负例 PASS。
|
||||
|
||||
本次未执行:Cursor Auto 真实派发、Cursor 项目角色配置安装、并行写锁实测、业务测试、产品 PI、浏览器、部署和清理。新规范的 V1–V10 实机清单是后续接入验收项。
|
||||
|
||||
## 7. 文档情景自审记录
|
||||
|
||||
审查者:Codex 主 Agent;独立性:self_review。以下为阅读草案逐项推演,结果仅表示文字路径可执行,不表示已运行客户端。
|
||||
|
||||
| 情景 | 对照位置 | 结论 |
|
||||
|---|---|---|
|
||||
| 只研究方案,未授权实现 | §2、S3 | 可交付研究,其后标不适用;不会顺推业务实现 |
|
||||
| 一处低风险文档修改 | §4、§7 | 主 Agent 自检,一份主文档可承载阶段,无需九个角色 |
|
||||
| 代码已修改但审查未回收 | S5、§5 | 不进入集成;后台结果需接收 |
|
||||
| 修复后旧审查/旧测试仍通过 | S5–S7 | 新版本需适用复核与验证,旧 PASS 不覆盖 |
|
||||
| readonly reviewer 需要报告 | §4、§7 | 子角色回传,主 Agent 在租约内转存 |
|
||||
| 测试生成缓存或写环境 | S6、§8 | verifier 可写但须明确产物范围/环境与租约 |
|
||||
| 两个子任务争用同路径 | §5 | 单写者或独立登记隔离,不能无锁并发 |
|
||||
| 子任务超时且副作用未知 | §6 | 保留 unknown,核对现场后决定恢复 |
|
||||
| 合并前 dev 已变化 | S7 | 重建候选并重新验证 |
|
||||
| 已合入但运行验收失败 | S8、S9 | 不宣布完成、不清理;修复/交接 |
|
||||
| owner 仍在 worktree 或有唯一日志 | S9、§5 | 保留现场,归档后由独立维护者复查 |
|
||||
| 会话中断后恢复 | §6、§7 | 从首个未满足门禁继续,核对未回收子任务 |
|
||||
|
||||
初次静态检查真实输出:`FILES=8 LOCAL_LINKS=84 STAGES=10 ISSUE_IDS=5 / PASS`。
|
||||
命令:`git diff --check`(exit 0);Python 内联检查全部本次 Markdown 变更(含 untracked)的相对链接/锚点、S0–S9、规则状态字段和 issue ID 唯一性(exit 0)。不验证外部网页永久可达或实际 Cursor 行为。
|
||||
只读 `agentctl docs drift`:status=ok、regressions=[];开放能力候选未修改,不等于产品就绪。
|
||||
|
||||
## 8. 后续决策:本机 PI 与可调整模型配置
|
||||
|
||||
用户在同一任务后续对话明确:子智能体采用 gmktec 本机 PI;仅允许 minimax-cn/MiniMax-M3、zai-coding-cn/glm-5.3、zai-coding-cn/glm-5.3-flash、qwen-token-plan-cn/qwen3.8-max、qwen-token-plan-cn/qwen3.8-flash。随后明确代码由 Cursor 实施,并因 M3 的实际使用反馈将其移出默认流程,最后确认该默认安排并要求可调整文档。
|
||||
|
||||
这些用户决策取代本报告前文 r1 中 Cursor 原生 .cursor/agents/inherit 的接入建议;前文保留为研究历史,不再作为当前实现方向。现行模型映射唯一来源为[模型配置](../ops/2026-09-24-subagent-model-config.md),流程草案同步到 r2。没有改变 Herdr 或产品 Runner。
|
||||
|
||||
2026-09-24 再次执行 pi --offline --no-extensions --no-skills --no-prompt-templates --no-themes --no-context-files --no-approve --list-models,exit 0;精确五个 provider/model 均存在。此命令没有模型推理,不证明各角色能力或连接状态。配置字段由主 Agent 人工读取,当前不含执行器/热加载/自动校验实现。
|
||||
|
||||
## 9. 执行器已接入(后续实现)
|
||||
|
||||
用户进一步授权接入自动调用 PI 的执行器。代码提交 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119,真实 Cursor CLI→MCP→PI 和 173 项工程回归通过,详情见[验证报告](../test-reports/2026-09-24-pi-executor-test-report.md)及[运行说明](../ops/2026-09-24-pi-subagent-executor.md)。前文关于未接入/未调用的说明属于当时研究阶段;当前交付范围与未覆盖项以上述新报告为准。完整流程草案审批、dev 集成和远端同步分别记录。
|
||||
@@ -0,0 +1,208 @@
|
||||
---
|
||||
title: "对话办公能力全景盘点"
|
||||
created: 2026-09-25
|
||||
owner: Cursor
|
||||
task_id: dialogue-office-expansion-2026-09-25
|
||||
policy_revision: cursor-governance-2026-09-24-r1 @ 44161d2ad2d7aada3e9ff88127b52148543278e5
|
||||
review_state: pending
|
||||
integration_state: pending
|
||||
deployment: not_required
|
||||
cleanup: pending
|
||||
remote_sync: not_requested
|
||||
status: done
|
||||
confidence: high
|
||||
---
|
||||
|
||||
# 调研:对话办公能力全景盘点
|
||||
|
||||
## 范围与授权
|
||||
|
||||
- **用户目标**:以「对话辅助办公」为初衷,最大限度扩展对话可操作范围;**创建项目、添加成员、设置等治理结构操作保持 UI 专属**。
|
||||
- **本轮交付**:研究报告 + 分期整改计划(文档落盘);P0–P3 **实施另起任务**。
|
||||
- **允许写路径**:`.doc/audit`、`.doc/remediation`。
|
||||
- **基线 SHA**:`44161d2ad2d7aada3e9ff88127b52148543278e5`(建场时 local `dev`)。
|
||||
- **非目标**:不改产品代码、不更新 CURRENT/FEATURE-MATRIX/gap-matrix、不部署。
|
||||
- **整改方案**:[2026-09-25-dialogue-office-expansion-plan.md](../remediation/2026-09-25-dialogue-office-expansion-plan.md)
|
||||
|
||||
## 结论
|
||||
|
||||
1. 注册表共 **32** 个 ActionKey(非早期估计的 34);主链路与 intentflow 计划执行面 **双轨脱节**:计划层 U11/U12 已把部分键 live 化,单意图协调层仍对认领/送审/工作流触发等返回「假成功」话术。
|
||||
2. HTTP **169** 条路由可按对话边界分为:可操作候选 **A=46**、只读查询 **B=66**、UI 专属写/管理台 **C=44**、平台基线 **13**。
|
||||
3. 消除假成功、打通 dry-run、接真实查询源、再扩新写意图,应按 P0→P3 分期;一律复用 doc-review 四道防线(识别分流 → 话语分类 → 角色×状态出卡 → 执行二次鉴权),两步确认 + 服务端权威校验。
|
||||
|
||||
## 证据
|
||||
|
||||
| 项 | 路径/命令 | 结果 |
|
||||
|----|-----------|------|
|
||||
| ActionKey SSOT | `internal/intent/registry.go` `registerBuiltinActions` L145–187 | **32** 键 |
|
||||
| 主链 docgov | `internal/coordinator/engine_docgov.go` | claim/submit 假成功;approve/reject 有 PendingAction |
|
||||
| 主链 workflow | `internal/coordinator/engine_workflow.go` | switch 确认闭环断裂;trigger 引导 UI |
|
||||
| intentflow dry-run | `internal/app/intentflow/expansion.go` L195–216 | docgov 5 dry-run + run-control 2 dry-run |
|
||||
| HTTP 路由 | `rg 'mux\.HandleFunc\("' internal/server/server.go internal/server/document_revision_handlers.go` | **169** |
|
||||
| 样板 | doc-review-lifecycle `09fe9723`;`card_policy.go` / `recognizer_matchers_docgov.go` / `action_executor.go` | 四道防线可复用 |
|
||||
|
||||
## 1. 意图执行矩阵(32 ActionKey)
|
||||
|
||||
**执行类别说明**
|
||||
|
||||
| 类别 | 含义 |
|
||||
|------|------|
|
||||
| `real-exec` | 协调层或 PendingAction 已调用领域服务真写 |
|
||||
| `pending-action` / `confirm-card+pending` | 出确认卡或挂起期望,确认后 `action_executor` 真写 |
|
||||
| `query-direct` | 只读查询,直接回复(可能含硬编码兜底) |
|
||||
| `prose-only` | 仅自然语言,无业务副作用(或明确拒绝) |
|
||||
| `假成功` | StatusAccepted/成功话术,但未调用权威写服务 |
|
||||
| `dry-run` | intentflow Owner 返回 `validated_only` receipt,无副作用 |
|
||||
|
||||
| ActionKey | 中文 | 主链类别 | 计划链(intentflow) | 主处理 | 后端 owner |
|
||||
|-----------|------|----------|----------------------|--------|------------|
|
||||
| `project.advisory` | 进展/风险查询 | query-direct | QueryOwner | `engine_query.go:handleQueryProgress` | 协调层/LLM |
|
||||
| `project.fact.supplement` | 补充项目事实 | real-exec | Mutate(flag 下 dry→live) | `engine_stage.go:handleSupplementInfo` | ctxmgr / MutateOwner |
|
||||
| `project.stage.advance` | 推进阶段 | real-exec / 无 runner 时 prose 模拟 | — | `engine_stage.go:handleAdvanceStage` | stageflow |
|
||||
| `task.run` | 触发生成任务 | real-exec | TaskRunAdapter | `engine_task.go:handleTriggerTask` | stageflow / taskrun |
|
||||
| `task.run.adhoc` | 特设任务 | real-exec | — | `engine_task.go:handleTriggerAdhocTask` | 同上 |
|
||||
| `conversation.chat` | 闲聊 | prose-only | — | `engine_consult.go:handleCasualChat` | dialogue LLM |
|
||||
| `conversation.decline` | 暂缓建议 | prose-only | — | `engine_stage.go:handleDeclineExpectation` | 上下文 |
|
||||
| `document.claim` | 认领文档 | **假成功** | live(U11) | `engine_docgov.go:250–277` | 主链仅改 Claimed 列表;计划→docgov |
|
||||
| `document.review.submit` | 提交审核 | **假成功** | live(U11) | `engine_docgov.go:280–295` | 主链纯文案;计划→`SubmitForReview` |
|
||||
| `document.review.approve` | 审核通过 | pending-action | **dry-run** | `engine_docgov.go:handleDocGovApprove` | `docgov.ReviewApprove` |
|
||||
| `document.review.reject` | 审核驳回 | confirm-card+pending | **dry-run** | `engine_docgov.go:handleDocGovReject` | `docgov.ReviewReject` |
|
||||
| `document.final.approve` | 终审批准 | confirm-card+pending | **dry-run** | 同上 Approve 分支 | `docgov.ApproverApprove` |
|
||||
| `document.final.reject` | 终审驳回 | confirm-card+pending | **dry-run** | 同 reject | 同上 |
|
||||
| `document.proposal.decide` | 提案裁决 | confirm 分支真挂起 / **默认分支假成功** | **dry-run** | `engine_docgov.go:298+` | confirm_*→PendingAction |
|
||||
| `regulation.query` | 法规查询 | query-direct | QueryOwner | `engine_query.go:handleQueryRegulations` | kb.Client + 模板兜底 |
|
||||
| `case.query` | 相似案例 | query-direct | QueryOwner | `engine_query.go:handleQuerySimilarCases` | SearchSimilarCases + **硬编码案例** |
|
||||
| `permission.query` | 权责查询 | query-direct | — | `engine_query.go:handleQueryUserRights` | UserDocs 上下文 |
|
||||
| `document.reject_reason.query` | 驳回原因 | query-direct | — | `engine_query.go:handleQueryRejectReason` | 黑板 + default 文案 |
|
||||
| `card.confirm` | 确认挂起期望 | confirm 元动作 | — | expectation 映射 | 路由至目标 intent |
|
||||
| `project.stage.execute` | 阶段执行确认 | 注册有、switch **无独立 case** | — | 实际走 advance | 同 advance |
|
||||
| `security.forbidden` | 安全禁止 | prose-only | RejectPlan | `engine_consult.go` | — |
|
||||
| `workflow.switch` | 切换激活工作流 | **假成功(确认后无执行)** | **dry-run** | `engine_workflow.go:12–59` | **边界上属结构治理 → 宜诚实拒绝/引导 UI** |
|
||||
| `workflow.run` | 运行工作流 | **假成功(引导 UI)** | live(U12) | `engine_workflow.go:62–90` | 计划→`CreateWorkflowRun` |
|
||||
| `workflow.status.query` | 工作流状态 | query-direct | — | `engine_workflow.go:93` | UserProjectContext |
|
||||
| `document.status.query` | 文档状态 | query-direct(常空模板) | — | `engine_workflow.go:117` | 模板/document_summary |
|
||||
| `conversation.help` | 能力帮助 | query-direct | — | `engine_workflow.go:139` | AvailableActions |
|
||||
| `conversation.unsupported` | 不支持 | prose-only | — | `engine_workflow.go:159` | — |
|
||||
| `run.status.query` | 运行状态 | query-direct | — | `engine_run.go:handleRunStatusQuery` | WorkDir |
|
||||
| `run.resume` | 续跑 | confirm-card+pending | live(U12) | `engine_run.go:handleRunResume` | taskrun |
|
||||
| `run.restart` | 重启 | confirm-card+pending | **dry-run** | `engine_run.go:handleRunRestart` | taskrun.restart |
|
||||
| `project.impact.analyze` | 影响分析 | query-direct | — | `impact_actions.go` | ImpactActions |
|
||||
| `project.doc.revise_propose` | 修订提案 | confirm-card+pending | — | `impact_actions.go` | ProposeRevision |
|
||||
|
||||
### 1.1 假成功清单(主链路优先)
|
||||
|
||||
| # | Legacy / Key | 文件:行号 | 当前行为 | P0 建议 |
|
||||
|---|--------------|-----------|----------|---------|
|
||||
| 1 | `DOCGOV_CLAIM` / `document.claim` | `engine_docgov.go:250–277` | 仅 append `UserDocs.Claimed`,回复「已成功认领」,不调 docgov | 真执行 `RecordDocumentViewed`/claim API + 确认(若需) |
|
||||
| 2 | `DOCGOV_SUBMIT_REVIEW` / `document.review.submit` | `engine_docgov.go:280–295` | 纯成功文案,无状态变更 | 真执行 `Gov.SubmitForReview` + 角色门禁 |
|
||||
| 3 | `DOCGOV_PROPOSAL_DECIDE` 默认分支 | `engine_docgov.go:383–397` | 非 confirm_* 时按 proposal_action 返回采纳/拒绝文案,不写文档 | 默认分支诚实澄清或走确认卡;禁止假成功 |
|
||||
| 4 | `SWITCH_WORKFLOW` / `workflow.switch` | `engine_workflow.go:12–59` | 设 NextExpectation 要求确认,**确认后无写路径** | **诚实拒绝**:属 UI 专属(`PUT …/active-workflow`);或确认后明确「请在设置面板操作」 |
|
||||
| 5 | `TRIGGER_WORKFLOW` / `workflow.run` | `engine_workflow.go:62–90` | 「请在面板确认」话术,不创建 run | 确认卡 + `CreateWorkflowRun`(对齐 U12) |
|
||||
|
||||
附带(非计划 P0 五处,但同类):无 runner 时 `ADVANCE_STAGE`/`TRIGGER_TASK` 模拟成功;`VIEW_DOC` lifecycle 空模板。
|
||||
|
||||
### 1.2 intentflow 仍 dry-run 的键
|
||||
|
||||
**DocGov**(`docGovActionKeys` 7 − `DocGovLiveActionKeys` 2 = **5**):
|
||||
|
||||
- `document.review.approve`
|
||||
- `document.review.reject`
|
||||
- `document.final.approve`
|
||||
- `document.final.reject`
|
||||
- `document.proposal.decide`
|
||||
|
||||
**Run-control**(4 − live `workflow.run`/`run.resume` = **2**):
|
||||
|
||||
- `workflow.switch`(计划层 dry-run;产品边界建议永久不 live 写,改为拒绝)
|
||||
- `run.restart`
|
||||
|
||||
见 `internal/app/intentflow/expansion.go` L195–216;dry-run 行为 `DryRunAdapter.Execute` → `validated_only`。
|
||||
|
||||
## 2. HTTP 169 路由 × 对话边界
|
||||
|
||||
**统计口径**:`internal/server/server.go` `Routes()` + `document_revision_handlers.go` `registerDocumentRevisionRoutes()` 中 `mux.HandleFunc("METHOD path")` = **169**。不含中间件 OPTIONS、SPA 静态子路径。
|
||||
|
||||
| 类别 | 计数 | 含义 |
|
||||
|------|-----:|------|
|
||||
| **A 对话可操作候选** | 46 | 读写副作用;对话须两步确认后经服务层落库 |
|
||||
| **B 只读查询候选** | 66 | GET + preview POST |
|
||||
| **C UI 专属** | 44 | 治理结构写 + admin 全域(含管理台只读) |
|
||||
| 平台基线 | 13 | health/ready、认证、SPA、`/me` 自服务 |
|
||||
| **合计** | **169** | |
|
||||
|
||||
### 2.1 A — 对话可操作候选(46)
|
||||
|
||||
| 模块 | n | 代表路径 | 对话意图现状 |
|
||||
|------|--:|----------|--------------|
|
||||
| docgov | 11 | `POST …/docgov/{claim,submit-review,review-decision,approver-decision,proposal,proposal/decide,comments,content,lease/*}` | 批准/驳回已打通;claim/submit 主链假成功;comments 等偏 UI |
|
||||
| docrevision | 2 | `PATCH …/documents/{id}/content` · `POST …/agent-candidates/{id}/decision` | 正文 PATCH 仅 HTTP;候选决策可对话扩展 |
|
||||
| trace | 6 | `POST …/trace/{index,analyze}` · `…/edges/{id}/decision` · `…/reopen` · `…/recheck/…/clear` | 影响分析意图有;**边裁决/重开仅 HTTP** |
|
||||
| 补充批次 | 1 | `POST …/supplement-impacts/{batch_id}/decision` | 补充意图有;批次确认可对话化 |
|
||||
| 工作流运行(非结构) | 2 | `POST …/workflows/{key}/run` · `…/stages/{stage}/advance` | run 主链假成功;advance 有意图 |
|
||||
| 任务执行 | 6 | `POST …/tasks/{run,run/stream,runs}` · `…/{cancel,resume}` | 触发/续跑已打通 |
|
||||
| 对话写 | 8 | `POST …/chat*` | 会话基础设施 |
|
||||
| 意图计划 | 1 | `POST …/intent-plans/{id}/decisions` | intentflow + HTTP 双通道 |
|
||||
| 自由文档 | 6 | `POST/PUT/DELETE …/freeform-documents*` | **仅 HTTP** → P3 候选 |
|
||||
| 资产 | 2 | `POST …/assets` · `…/reparse` | **仅 HTTP** → P3 |
|
||||
| 通知 | 1 | `PATCH …/notifications/{id}` | **仅 HTTP** → P3 |
|
||||
| 用户偏好 | 1 | `PUT …/context/user/preference` | 低优先级 |
|
||||
|
||||
### 2.2 B — 只读查询候选(66)
|
||||
|
||||
项目/工作流/成员/设置 **GET**、termination/activation **preview**、chat 历史检索、docgov audit/comments GET、修订 ledger GET、资产 raw、通知列表、context/cases 等。
|
||||
|
||||
对话已覆盖:进展、文档/工作流/运行态、驳回原因、法规/案例/权限(案例与进展有硬编码兜底)。
|
||||
仍偏 HTTP:职责现状、修订版本/diff、trace 图、终止预览、成员列表只读(允许对话只读引导,禁止代写)。
|
||||
|
||||
### 2.3 C — UI 专属红线(44,对话永久禁写)
|
||||
|
||||
| 模块 | 写操作(禁入) |
|
||||
|------|----------------|
|
||||
| 项目/成员 | `POST /projects` · `POST|PUT|DELETE …/members` |
|
||||
| 职责 | `PATCH …/doc-tasks/{taskKey}/duties` |
|
||||
| 工作流结构/生命周期 | `PUT …/workflow-plan` · `PUT …/active-workflow` · `POST …/workflow-instances/activate` · `POST …/terminate` |
|
||||
| Admin | 角色/用户/密码/工作流定义 publish·retire/模板/config/system settings/maintenance/workspaces cleanup |
|
||||
|
||||
对话侧应对命中措辞走 `security.forbidden` / `conversation.unsupported`,**仅允许只读查询与引导**(如读职责现状、`termination-preview`)。
|
||||
|
||||
> **澄清**:`workflow.switch`(改 active-workflow)落入 C;`workflow.run`(创建运行实例)落入 A。P0 对前者诚实拒绝,对后者真执行。
|
||||
|
||||
## 3. 查询硬编码兜底
|
||||
|
||||
| 场景 | 位置 | 问题 |
|
||||
|------|------|------|
|
||||
| 相似案例 | `engine_query.go:420–426` | 无数据时硬编码 PRJ-2025-008 / PRJ-2024-019 |
|
||||
| 驳回原因 | `engine_query.go:260–276` + `card_policy.go:defaultRejectReasonText` | 黑板/事件捞取失败则默认文案 |
|
||||
| 法规 | `engine_query.go:382–388` | KB 空则 GB/YY 模板 |
|
||||
| 进展简报 | `engine_query.go:83–164` | 默认项目名与长硬编码段落 |
|
||||
| 文档状态 | `engine_workflow.go:126–129` | lifecycle 空 → 引导面板 |
|
||||
|
||||
## 4. 复用样板:doc-review 四道防线
|
||||
|
||||
参考合入/分支证据:`feature/doc-review-lifecycle-2026-09-25` @ `09fe9723`(批注/重开/积压/送审真执行)。
|
||||
|
||||
| 防线 | 符号 | 要点 |
|
||||
|------|------|------|
|
||||
| ① 识别分流 | `recognizer_matchers_docgov.go:matchDocGovAction` | 查询语气不误路由写动作 |
|
||||
| ② 话语分类 | `card_policy.go:ClassifyRejectUtterance`(Web 对称) | QUERY / EXECUTE / OTHER |
|
||||
| ③ 角色×状态出卡 | `ResolveRejectCard` / `buildRejectConfirmCard` | 无权限不出危险按钮 |
|
||||
| ④ 执行二次鉴权 | `handleDocGovReject/Approve` + `chat/action_executor.go` | 确认后调 `GovernanceEngine` |
|
||||
|
||||
后续写意图扩展必须复制该模式,禁止「话术成功、服务未写」。
|
||||
|
||||
## 5. 开放问题
|
||||
|
||||
- `project.stage.execute` 注册未接线:是否删除或显式映射到 advance(实施期决定)。
|
||||
- 自由文档/通知/资产对话化的产品优先级与确认文案(P3 开工前再确认)。
|
||||
- `workflow.switch` 是否保留意图仅作「引导 UI」还是识别层直接 `unsupported`(推荐后者,减少假确认)。
|
||||
|
||||
## 建议动作
|
||||
|
||||
见整改计划 P0–P3;本调研 **status=done** 仅表示盘点可审,**不代表问题已修复**。
|
||||
|
||||
## 状态与交接
|
||||
|
||||
- 产物:本文 + [整改计划](../remediation/2026-09-25-dialogue-office-expansion-plan.md)
|
||||
- 实施:另起 `feature/dialogue-office-p0-…` 等任务;每期独立验证与验收
|
||||
- CURRENT / MATRIX / gap-matrix:本轮不动
|
||||
- catalog:`feature=dialogue-office`,scope `.doc/audit`+`.doc/remediation`;与 `docgov` feature claim 硬冲突,故未占用 `docgov` 键
|
||||
@@ -0,0 +1,267 @@
|
||||
---
|
||||
title: "系统全面 Code Review(local_dev tip)"
|
||||
status: done
|
||||
created: 2026-09-26
|
||||
owner: Cursor
|
||||
task_id: "system-code-review-2026-09-26"
|
||||
policy_revision: "agent-governance-2026-09-21-r1 + cursor-governance-2026-09-24-r1 @ f4c1b73f28580ad3df6db4f9ec0a80057006e516"
|
||||
review_state: accepted
|
||||
integration_state: integrated
|
||||
deployment: not_required
|
||||
cleanup: done
|
||||
remote_sync: not_requested
|
||||
updated: 2026-09-26
|
||||
severity: high
|
||||
---
|
||||
|
||||
# 系统全面 Code Review(local_dev tip)
|
||||
|
||||
## 范围与授权
|
||||
|
||||
- **用户目标**:对系统做一次全面 code review,并按规范形成报告;**不允许实施修复**,只形成报告。
|
||||
- **被审对象**:本地 `dev` tip `f4c1b73f28580ad3df6db4f9ec0a80057006e516`(merge: swboot-closeout-2026-09-26-r3);运行态参考 no-docker local_dev(`bin/agent-server`,schema 75),本报告以代码与门禁证据为主。
|
||||
- **允许写路径**:`.doc/`(本审计主文档、INDEX、short-term 任务记录)。
|
||||
- **交付终点**:可审审计报告 + 索引挂接;不改业务代码、不改 gap-matrix / FEATURE-MATRIX 状态值、不部署。
|
||||
- **非目标**:逐文件全量行审、依赖 CVE 扫描、前端 XSS 系统化、动态渗透、实施整改。
|
||||
- **方法**:并行四轴审查(架构边界 / 安全 / 可维护性 / 关键执行路径)+ 本机 `./scripts/arch-check.sh --mode block`、规模盘点与关键片段复核。
|
||||
|
||||
## 问题登记与经验检索
|
||||
|
||||
- **issue_id**:本轮不新建 ISSUES 行;发现项以本报告 FIND-* 编号跟踪。若后续授权修复,再按 [闭环规范](../ops/2026-09-23-issue-learning-workflow.md) 升 issue。
|
||||
- **检索词**:`IDOR`、`GetUserContext`、`session_id`、`validated_only`、`fencing`、`arch-check`、`table_owners`、`ALLOW_IN_MEMORY`、`sh -c`、`swboot`。
|
||||
- **命中**:历史审计见 [INDEX](./INDEX.md)(模块耦合 2026-09-20、对话办公盘点 2026-09-25、gap-matrix);经验库无与本轮 FIND-SEC-01 完全同题的已关闭 lesson。**采纳检查**:对照模块开发规范 §2/§4、authz fail-closed 惯例、intentflow 注释契约。
|
||||
|
||||
## 总判(Verdict)
|
||||
|
||||
`arch-check --mode block` **PASS**,且多项生产门禁(任务路径 stub 拒绝、FAV outbox consumer 多层禁用、docgov 角色不信任 body)仍然有效。但系统存在三类结构性风险:
|
||||
|
||||
1. **安全旁路**:会话上下文 IDOR(已证实);Authorizer 无池 fail-open;swboot `sh -c` + 前缀白名单。
|
||||
2. **门禁空心化**:未登记表的 SQL 写被 arch-check **静默跳过**;server 仍持 `Runtime.Pool` 并直查/直写。
|
||||
3. **多入口编排**:docgov / 多意图 / flag 面平行三套,关闭开关时存在静默降级。
|
||||
|
||||
本轮 **不改变** gap-matrix 的 `production_ready` 叙事;下列 critical/high 建议作为独立 remediation 候选,待授权后再立项。
|
||||
|
||||
## 现象
|
||||
|
||||
只读审查与门禁核验,无用户报障个案。审查期望:合入 swboot / dialogue-ctx / jevdecide / semantic-replace 后的 tip 在模块边界、鉴权与关键执行路径上仍满足生效规范。实际:门禁绿,但多处规范语义与实现分叉(见 Findings)。
|
||||
|
||||
## Findings(按严重度)
|
||||
|
||||
置信度说明:`verified` = 父会话已打开源码复核;`agent` = 子代理报告、抽样一致;`inferred` = 机制推断未跑动态用例。
|
||||
|
||||
### Critical
|
||||
|
||||
#### FIND-SEC-01 — 会话消息 IDOR(`session_id` 无归属校验)
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 授权 / IDOR |
|
||||
| 位置 | `internal/server/handlers_context.go:17-50`;`internal/ctxmgr/manager.go:377-385` |
|
||||
| 证据 | `handleGetUserContext` 仅校验 `user_id` 为本用户/管理员;`GetUserContext` 对 `chat_messages` 使用 `WHERE session_id = $1` **无 owner 条件**。对照 `chatflow` 读路径会校验会话归属。 |
|
||||
| 影响 | 已登录用户若获知他人 `session_id`,可读取对方最近聊天正文。 |
|
||||
| 置信度 | verified · high |
|
||||
| 修复方向(不实施) | 复用 chatflow 会话授权;或按 `session.owner_id`/`user_id` 过滤后再返回。 |
|
||||
|
||||
#### FIND-ARCH-01 — arch-check 对未登记表静默跳过(表唯一写者门禁盲区)
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 门禁 / 模块边界 |
|
||||
| 位置 | `internal/archtest/scan.go:198-205`;`module-boundaries.yaml` `table_owners`(约 59 表) |
|
||||
| 证据 | `if !tracked { continue }`;本机 tip:`swboot_controlled_executions` / `projects` / `project_source_bindings` / `outbox_events` **UNTRACKED**;`arch-check --mode block` 仍 PASS。 |
|
||||
| 影响 | 新表(含 swboot)可任意包写入而不触发 block;「表唯一写者」对未入库表无强制力。 |
|
||||
| 置信度 | verified · high |
|
||||
| 修复方向 | 未登记表的生产写应变 fail-closed,或强制登记。 |
|
||||
|
||||
#### FIND-ARCH-02 — server 持 Pool 直装 swboot 并 SQL 旁路
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 组合根越界 |
|
||||
| 位置 | `internal/server/swboot_handlers.go`(NewPGRepoAllowlist / ControlledPatchExecutor / 直查 bindings & executions) |
|
||||
| 证据 | 与模块规范 §2.1「server 只拿用例或端口」冲突;`app.Build` 已另有 allowlist 装配。 |
|
||||
| 影响 | HTTP 层成为第二组合根;边界回归。 |
|
||||
| 置信度 | agent · high(与规范条文一致) |
|
||||
| 修复方向 | 收成 app 用例端口;禁止 handler 使用 `rt.Pool`。 |
|
||||
|
||||
### High
|
||||
|
||||
#### FIND-SEC-02 — Authorizer 无池时成员判定 fail-open
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 鉴权 fail-open |
|
||||
| 位置 | `internal/authz/authorizer.go:112-114`、`205-207` |
|
||||
| 证据 | `!a.enabled()`(pool==nil)时 `IsProjectMember`/`IsProjectOwner` 对 `userID>0` 返回 true;组合根始终 `NewAuthorizer(pool)`,nil pool 时 `authorizer()!=nil`,绕过「nil → failClosed」分支。 |
|
||||
| 影响 | AllowInMemory / 无库误配时,任意登录用户可访任意 `project_id`。生产有 `ALLOW_IN_MEMORY` 门禁则触发面缩小,**机制本身仍 fail-open**。 |
|
||||
| 置信度 | verified · high |
|
||||
|
||||
#### FIND-SEC-03 — swboot 受控执行:`sh -c` + basename 前缀白名单
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 命令注入面 / 边界语义 |
|
||||
| 位置 | `internal/swboot/executor.go`(`sh -c`、前缀匹配);`ApproveMerge` 恒拒 |
|
||||
| 证据 | 允许判定为字段首段 basename 前缀;命令经 shell 执行。执行器自身不做 merge/push,但若 admin allowlist 含 `git`/`bash` 等,客户端可间接 push/merge/deploy。 |
|
||||
| 影响 | 在 creator + 宽松 allowlist 前提下,隔离 worktree 内可越出「测试命令」意图。 |
|
||||
| 置信度 | agent · high |
|
||||
| 说明 | 与 MATRIX「永不 merge/push/deploy」在「执行器 API」语义下仍成立;真正边界在 **admin 命令白名单粒度**。 |
|
||||
|
||||
#### FIND-FLOW-01 — intentflow `validated_only`/`proposed` 可经 confirm 进入 dispatch
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 执行模式门禁 |
|
||||
| 位置 | `internal/app/intentflow/plans.go:365-376`;`intent_plan_handlers.go:86-88`;`ExecuteClaimed` 不读 `ExecutionMode` |
|
||||
| 证据 | `DecisionConfirm` **允许** `PlanProposed`;确认后 HTTP 调用 `DispatchEligible`;`AllowedModes` 策略字段几乎未被执行路径使用。 |
|
||||
| 影响 | shadow「安全」依赖「无人 Confirm」,而非执行器硬拒绝;U10/U11 live 已接线时可升级为真实写。 |
|
||||
| 置信度 | verified · high(静态);未做动态 confirm 用例 |
|
||||
|
||||
#### FIND-QUAL-01 — docgov / 多意图多入口并行(职责扩散)
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 可维护性 / 双写路径 |
|
||||
| 位置 | chat `docgov.*` PendingAction;`app/docgov_owner.go` `document.*`;`server/handlers_docgov.go`;intent vs intentflow 双套 flags |
|
||||
| 证据 | 同一 `GovernanceEngine` 三入口;`intent.FeatureFlags` 与 `intentflow.FeatureFlags` 并存;Coordinator ~40 intent case + intentflow OwnerMux 平行。 |
|
||||
| 影响 | 鉴权/确认/审计易漂移;回归矩阵笛卡尔积;开关关闭时 Mux→Query 静默降级(FIND-FLOW-02)。 |
|
||||
| 置信度 | agent · high |
|
||||
|
||||
#### FIND-ARCH-03 — bizdev / Runtime / 万能 Engine 门面残留
|
||||
|
||||
| 项 | 内容 |
|
||||
|---|---|
|
||||
| 类别 | 架构债 |
|
||||
| 位置 | `internal/bizdev/service.go`;`internal/app/app.go` Runtime;`docgov`/`coordinator` Engine |
|
||||
| 证据 | bizdev 自开池并装配多引擎;Runtime 暴露 Pool+数十服务;Engine 方法面极大。arch-check allowlist 放行上帝包,PASS ≠ 模块化健康。 |
|
||||
| 影响 | 新功能默认堆 handler/Runtime;与解耦批次目标持续摩擦。 |
|
||||
| 置信度 | agent · high |
|
||||
|
||||
### Medium
|
||||
|
||||
| ID | 摘要 | 关键位置 | 置信度 |
|
||||
|---|---|---|---|
|
||||
| FIND-SEC-04 | 授权拒绝 404/403 区分,泄露资源存在性 | `task_run_auth.go`、`auth_helpers.go` | agent |
|
||||
| FIND-SEC-05 | Chat SSE:阶段拒绝在 Flush 之后;`user_role` 可写入会话上下文 | `sse.go` | agent |
|
||||
| FIND-SEC-06 | 对话 `agent.NewBackend` 对未知名默认 stub;生产密钥校验不禁 stub | `agent/backend.go`、`config.go` | agent |
|
||||
| FIND-SEC-07 | 未认证 `/api/v1/vault/status` 暴露 FAV 开关 | `auth_middleware.go`、`vault.go` | agent |
|
||||
| FIND-SEC-08 | 会话 token 存 `localStorage`(XSS 放大) | `web/src/api/auth.ts` | agent |
|
||||
| FIND-DOC-01 | docgov 省略 fencing token 仍可写;heartbeat persist / squad reclaim fail-open | `docgov/lease.go` | agent |
|
||||
| FIND-DOC-02 | `CommitAgentVersion` 与 edit lease 解耦竞态面 | `docrevision/service_agent.go` | agent |
|
||||
| FIND-FLOW-02 | `OwnerMux` 在 U10/U11/U12 关闭时静默降级到 Query | `intentflow/mux.go` | agent |
|
||||
| FIND-ARCH-04 | notification handler 端口失败后回落 Pool SQL | `notification_handlers.go` | agent |
|
||||
| FIND-ARCH-05 | 提案批准后 handler 裸 goroutine 副作用 | `handlers_docgov.go` | agent |
|
||||
| FIND-ARCH-06 | 错误信封拼接 `err.Error()` | 多 handler | agent |
|
||||
| FIND-QUAL-02 | 全局 flag/metrics 损害并行测试隔离 | `intent/flags.go`、`intentflow/*` | agent |
|
||||
| FIND-QUAL-03 | 巨石文件逼近/超过规范阈值(见规模盘点) | squad/taskrun/server/web | verified |
|
||||
|
||||
### Low / 契约说明
|
||||
|
||||
| ID | 摘要 |
|
||||
|---|---|
|
||||
| FIND-JEV-01 | jevdecide assist 失败为 **fail-open 回规则**(不编造);若产品要求「jev 挂则拒答」则不满足——属契约澄清,非实现疏忽。 |
|
||||
| FIND-DOC-03 | summarizer 注释仍写「REPLACE 不接线」,与已合入 `applySemanticReplace` 矛盾。 |
|
||||
| FIND-EVT-01 | 事件 payload 密钥过滤面窄于 taskrun `StripSecrets`(子串级)。 |
|
||||
|
||||
## 同类问题与影响范围
|
||||
|
||||
| 关联场景 | 共用机制 | 检查与证据 | 判定 |
|
||||
|---|---|---|---|
|
||||
| chatflow 读会话 | 会话 owner 校验 | chatlog Adapter authorize | 主路径健全;**旁路** `GetUserContext` 缺校验 |
|
||||
| 任务 SSE 鉴权 | Flush 前 RequireProjectAccess | gap-matrix AUTH-TASK-SSE PASS | 项目门健全;阶段拒绝在流后属中危差异 |
|
||||
| FAV outbox | Enabled:false + Register/Claim 硬拒 | registry/dispatcher/eventsconsumer | **未见旁路打开** |
|
||||
| swboot ApproveMerge | 恒拒 | repo_allowlist | 自身 API 健全;命令白名单是真边界 |
|
||||
| 生产 ALLOW_IN_MEMORY | validateProductionSecrets | config.go | 非空 Env 的 prod 有防护;空 Env+内存组合仍危险 |
|
||||
|
||||
**未覆盖(明确边界)**:govulncheck/npm audit;MinerU/Embedding SSRF 动态验证;FAV degraded 跨项目读 E2E;Markdown XSS 系统化;全量 `BeginTx` 持锁外呼追踪。
|
||||
|
||||
## 方案与验收(仅建议,本轮不实施)
|
||||
|
||||
### 建议优先级
|
||||
|
||||
1. **P0**:FIND-SEC-01(IDOR)— 补会话归属;加回归(他用户 session_id → 403/空)。
|
||||
2. **P0**:FIND-ARCH-01 — arch-check 未登记表 fail-closed;补登记 swboot/projects 等属主。
|
||||
3. **P1**:FIND-SEC-02 — Authorizer `!enabled()` 改 fail-closed 或与 `failClosedAuthz` 对齐。
|
||||
4. **P1**:FIND-SEC-03 / FIND-FLOW-01 — argv 化命令 + 收紧白名单;Confirm 拒绝 `validated_only`/`proposed` 或执行器硬读 mode。
|
||||
5. **P2**:收敛 docgov/多意图单一写路径与单一 flag 面;收回 server Pool。
|
||||
|
||||
### 验收提示(未来修复任务)
|
||||
|
||||
按 [验证契约](../ops/2026-09-21-validation-contract.md)「问题修复的回归范围」:原例 + 同类旁路 + 正常授权路径;工程侧补 `archtest` 用例证明未登记表 block。
|
||||
|
||||
## 严重度
|
||||
|
||||
报告整体:`high`(存在已证实 IDOR + 门禁盲区;未做动态利用)。
|
||||
|
||||
## 关联整改
|
||||
|
||||
- 既有: [模块解耦分批](../remediation/2026-09-20-module-decoupling-batch-plan.md)、[对话办公扩展](../remediation/2026-09-25-dialogue-office-expansion-plan.md)、[gap-matrix](../remediation/gap-matrix.md)
|
||||
- **本轮未新建 remediation 文件**(用户禁止实施;方案仅建议)。授权后建议拆:`remediation/2026-09-26-system-code-review-followups.md`。
|
||||
|
||||
## 证据
|
||||
|
||||
### 门禁与规模(本机)
|
||||
|
||||
```text
|
||||
被审 SHA: f4c1b73f28580ad3df6db4f9ec0a80057006e516
|
||||
arch-check --mode block → production gate passed
|
||||
tracked table_owners ≈ 59;swboot_controlled_executions/projects/project_source_bindings/outbox_events = UNTRACKED
|
||||
|
||||
Go 生产文件 LOC 前列(非测试):
|
||||
cmd/bizdev-cli/main.go 1017
|
||||
internal/squad/workflow.go 963
|
||||
internal/server/task_run_handlers.go 858
|
||||
internal/taskrun/manager.go 813
|
||||
…
|
||||
|
||||
Web:
|
||||
web/src/App.tsx 1748
|
||||
web/src/engine/docxRenderer.ts 1263
|
||||
…
|
||||
```
|
||||
|
||||
### 子代理
|
||||
|
||||
| 轴 | 类型 | 用途 |
|
||||
|---|---|---|
|
||||
| 架构边界 | architecture-critic | 模块规范对抗审 |
|
||||
| 安全 | security-auditor | OWASP 向只读审(无 PoC) |
|
||||
| 可维护性 | thermo-nuclear-code-quality-review | 上帝对象/双路径/开关丛林 |
|
||||
| 关键路径 | code-explorer | intentflow/docgov/swboot/FAV/jev |
|
||||
|
||||
### 运行态(旁证,非本报告验收对象)
|
||||
|
||||
此前会话:no-docker `bin/agent-server` `vcs.revision` = tip;`/api/v1/health`+`/ready` ok,schema 75。
|
||||
|
||||
## 开放问题
|
||||
|
||||
1. FIND-FLOW-01:产品是否故意允许对 shadow `proposed` 计划一键 Confirm 升 live?若否,属缺陷;若是,应改文档/MATRIX 与执行器注释。
|
||||
2. FIND-JEV-01:assist「失败 fail-closed」的产品定义是否等于「回退规则」?
|
||||
3. 是否授权将 FIND-SEC-01/ARCH-01 升 ISSUES 并开 remediation?
|
||||
|
||||
## 修复经过与经验
|
||||
|
||||
- **本轮未实施任何代码修复**(用户硬约束)。
|
||||
- 不新增 lesson:发现尚未经验证修复闭环。
|
||||
- 复发提醒:旁路 HTTP(绕过 chatflow/Owner)是鉴权回归的高发点。
|
||||
|
||||
## 状态与交接
|
||||
|
||||
| 字段 | 值 |
|
||||
|---|---|
|
||||
| 任务状态 | `done`(研究产物可审) |
|
||||
| review_state | pending(待人工审阅报告) |
|
||||
| integration_state | pending(报告合入 local_dev 另走 integrate) |
|
||||
| deployment | not_required |
|
||||
| cleanup | pending |
|
||||
| remote_sync | not_requested |
|
||||
| 剩余工作 | 授权后开 P0 修复任务;本 worktree 合入/清理由独立维护者执行 |
|
||||
| 禁止续作 | 在本任务下直接改业务代码冒充「顺便修」 |
|
||||
|
||||
## Positive observations
|
||||
|
||||
1. `arch-check` 对**已登记** import/sql/path/event 仍 enforced。
|
||||
2. FAV outbox consumer `Enabled:false` 多层硬拒,未见旁路打开。
|
||||
3. 任务 SSE 项目鉴权在 Flush 前;docgov 角色取 principal 不信任 body。
|
||||
4. 语义摘要 shadow:lease 提交后再 Summarize,符合持锁不做外部 IO。
|
||||
5. swboot/jevdecide 领域包 import allowlist 自身较窄;污染主要在接线层。
|
||||
@@ -0,0 +1,344 @@
|
||||
---
|
||||
title: "多仓库架构研究证据与审查记录"
|
||||
date: 2026-09-28
|
||||
task_id: multi-repo-design-2026-09-28
|
||||
evidence_basis: current_source_and_readonly_api
|
||||
---
|
||||
|
||||
# 多仓库调研证据
|
||||
|
||||
范围:[待审方案](../remediation/2026-09-28-multi-repo-architecture-plan.md)。
|
||||
记录只读 API 和源码事实,不包含业务正文、凭证值、认证头、原始数据库或敏感截图。
|
||||
未对远端执行 POST/PATCH/DELETE,也未 push、部署或创建远端仓库。
|
||||
|
||||
## Git and Gitea
|
||||
|
||||
本地研究基线:dev@a3db288a7aa055ff5884e3aa4d91511959cff721,开始时主目录干净。
|
||||
任务 worktree:.worktrees/multi-repo-design-2026-09-28,分支 feature/multi-repo-design-2026-09-28。
|
||||
`git rev-list --left-right --count fabd85a65e15f3417431ba6f004a8bcdf9cb83cb...a3db288a7aa055ff5884e3aa4d91511959cff721` 返回 `0 306`。
|
||||
因此领先 306 不是仅依据缓存 origin/dev;远端实时 API 的 SHA 与缓存一致,且祖先关系已核对。
|
||||
本轮未 fetch 修改 remote-tracking ref,未同步远端。
|
||||
|
||||
Gitea GET /api/v1/version 返回 1.27.3。
|
||||
GET /api/v1/user/repos 分页(本次一页已取完六仓),仅保留所需元数据:
|
||||
|
||||
| 仓库 | private | empty | default_branch | description | 结论 |
|
||||
|---|---|---|---|---|---|
|
||||
| weichen/Agent-System | false | false | dev | 空 | 保留主仓 |
|
||||
| weichen/Agent-System-Squad | false | true | main | 空 | 名称可复用,尚无组件内容 |
|
||||
| weichen/Agent-System-Development-Documents | false | true | main | 空 | 可复用,导入内容须分类 |
|
||||
| weichen/Development-Guidelines | false | true | main | 空 | 可复用 |
|
||||
| weichen/Agent-System-Releases | false | true | main | 空 | 只适合公开发布目标 |
|
||||
| weichen/Development-Manager | false | false | dev | 空 | 已有治理工具,不应重建覆盖 |
|
||||
|
||||
仓库 has_actions=true 只证明设置开启,不证明 runner/CI/权限可用。
|
||||
所有六仓当前读取身份有 admin/push/pull 权限;此事实不扩大本轮授权。
|
||||
|
||||
Agent-System 实时分支摘要:
|
||||
- dev: fabd85a65e15f3417431ba6f004a8bcdf9cb83cb
|
||||
- test: 0e4b111dff3726f5379e8168e3d00a244e111747
|
||||
- main: 210fe4a7bb2fd56c34a215c53e07617cccf81e49
|
||||
- 三分支 protected=false,GET branch_protections 返回 []。
|
||||
|
||||
Development-Manager 的 branch_protections 同样返回 []。
|
||||
两仓 GET releases?limit=3 返回 [];只说明本次未列出发布记录,不把 Git tags 当 Releases。
|
||||
两仓 repository-level GET actions/runners 返回 runners=[];没有检查实例级/组织级 runner,不推断整个实例无 runner。
|
||||
四个 empty 仓的 branches 返回 null,与 empty 状态一起解释为没有可列出的分支,不虚构 main 已有提交。
|
||||
|
||||
读取本机 /swagger.v1.json:
|
||||
MergePullRequestOption 的 do enum 包含 merge/rebase/rebase-merge/squash/fast-forward-only/manually-merged;
|
||||
包含 head_commit_id、merge_commit_id、force_merge。
|
||||
BranchProtection 包含 required_approvals、dismiss_stale_approvals、block_on_outdated_branch、status_check_contexts、push/merge allowlist 等。
|
||||
这是字段证据,未验证运行语义;方案 U1/U2 要做授权演练。
|
||||
|
||||
## Existing Development Manager
|
||||
|
||||
远端 README/PROJECT/MIGRATION 当前可读。
|
||||
MIGRATION 记录:2026-09-24T15:39Z,从 Agent-System dev@edbe59247872ef5861bafd30068955e22288c6ff 复制式拆出;新初始历史,未携带 .locks。
|
||||
PROJECT 将其定位为治理工具权威演进仓,阶段 A 通过 projects 聚合本机各项目 .locks,阶段 B 中央 API 尚预留。
|
||||
这是仓库文档的当前声明,不等于运行态部署证明。
|
||||
|
||||
本机 Development-Manager 目录存在,dev@8867e38ceb7cc71fa65d1a0f80178faff53fcb4c,工作树干净,缓存 origin/dev 无领先/落后提示。
|
||||
本次未单独核对其远端 dev SHA,因此不声称实时完全同步。
|
||||
本机 Development-Guidelines 目录不存在;历史记忆中的同名旧工作区不作为当前事实。
|
||||
|
||||
## Squad Boundary Evidence
|
||||
|
||||
| 路径 | 当前机制 | 设计影响 |
|
||||
|---|---|---|
|
||||
| internal/squad/service.go:113 | Service 引用主仓 config.Config | 注入 Options,不反向依赖主仓 |
|
||||
| internal/bizdev/service.go:195 | 直接 squad.NewService(cfg) | 装配与适配保留产品应用 |
|
||||
| internal/squad/workflow.go:547 | agent.Request、重试/失败分类与物化 | 执行端口、失败语义、重试归属要显式 |
|
||||
| internal/squad/service.go:256 | 直接主仓 stream 事件 | Squad 事件由应用映射至 SSE/持久状态 |
|
||||
| internal/squad/workspace_adapter.go:6 | 返回主仓 WorkspaceRef | 适配留应用侧 |
|
||||
| internal/squad/service.go:524 | templates/xlsx/cdo_quote.xlsx | 运行包资产不能仅包含 Markdown |
|
||||
| internal/bizdev/service_task_finalize.go:68 | 质量失败短路 | 不可将执行完成等同正式提交 |
|
||||
| internal/bizdev/service_task_finalize.go:35 | 编制人提交身份与 OnBehalfOf 分离 | 不改变产品授权 |
|
||||
| .doc/system-design/module-boundaries.yaml:283 | 七包依赖 allowlist | 先解耦,再独立 Go 模块 |
|
||||
|
||||
rg 穷举正式 Go import 显示 Squad 直接使用方涉及 29 文件/9 目录,包括 bizdev/chat/coordinator/server/intent/materialindex/projectcontext 与 CLI/script。
|
||||
主模块 `go.mod` 为 `module chat-agent-system`,Go 版本声明 1.27.1;本轮不推断目标机器工具链已安装。
|
||||
独立模块继续 import 主仓 internal 包不可行。
|
||||
现行模块开发标准明确模块化单体;仓库独立不自动授权增加 RPC/微服务。
|
||||
|
||||
## Tooling and Documentation Evidence
|
||||
|
||||
| 路径 | 观察 | 必须适配 |
|
||||
|---|---|---|
|
||||
| scripts/agentctl.py:598–610 | Git common-dir 需等于 main/.git | 标准 submodule 的 .git 文件布局当前不支持 |
|
||||
| scripts/agent_worktree.py:95–102 | 要求主工作区 .git 为目录 | 不能仅改 agentctl 一个入口 |
|
||||
| scripts/agentctl.py:642–669 | 直接 sqlite3.connect 至本地主仓 .locks/state.sqlite | 多 clone 不是共享协调域 |
|
||||
| scripts/agentctl.py:2861 | 本地 manager.lock 与队列循环 | 本地 daemon 不等于跨机服务 |
|
||||
| scripts/agentctl.py:1599–1625 | 按父仓 staged 文件识别共享文档并查收据 | .doc gitlink 不能替代内容级检查 |
|
||||
| scripts/agentctl.py:1287 / 1333 / 2245 | git show / cat-file 读取 HEAD/dev 中的文档与证据 | 跨仓 repo+SHA+path 引用 |
|
||||
| internal/archtest/boundaries.go:107 | 机器模块契约位于 .doc | 留在代码仓,不作为普通文档搬离 |
|
||||
| scripts/candidate-images-build.sh:60 | 仅 git archive 主仓提交 | 子模块源码固定递归导出 |
|
||||
| scripts/pi_subagents.py、agentctl_w4.py、.cursor | 多处固定 .doc 位置 | 客户端入口、报告及治理一起迁移 |
|
||||
|
||||
主目录 agentctl status 本轮返回 status=ok、protocol version=1;
|
||||
实际 policy revision 为 agent-governance-2026-09-23-fav-constraint-restored。
|
||||
CURRENT 顶部历史摘要仍有 2026-09-23 信息,活跃任务表更晚;方案未用其历史环境状态代替 Git/API 现状。
|
||||
|
||||
## Build and Runtime Assets
|
||||
|
||||
- scripts/build-single-binary.sh 构建 Web,然后 CGO_ENABLED=0 构建 cmd/server,写入版本 ldflags;不是全平台发布流程。
|
||||
- web/embed.go 的 go:embed all:dist 可将前端纳入二进制。
|
||||
- templates/embed.go 仅嵌入 docs/*.md;internal/template/loader.go 读取 configs/agents 指令和 configs/shared/writing.md。
|
||||
- deploy/app/Dockerfile 仍显式复制 web/dist、迁移、templates、configs,构建 server/events。
|
||||
- internal/localpg/localpg.go 查找本机 pg_ctl;数据库不是被 Go 服务自带。
|
||||
- deploy/pi-agent/Dockerfile 使用 Node 22 与单独 PI 包,固定 CLI 0.85.1;Runner 是额外执行依赖。
|
||||
- .github/workflows/ci.yml 有 Go/PG/Web 验证;nightly-real-pi.yml 有 Gitea 专用 runner/上传兼容说明。
|
||||
- 主仓 tree 跟踪 docgov.test、notification.test、projectinstance.test、storage.test;制品仓应避免继续提交二进制正文,历史不自动重写。
|
||||
- 未编译新平台、未启动服务、未读模型密钥、未读取 IDE 中业务 output.md。
|
||||
|
||||
## Lessons Reused
|
||||
|
||||
检索 .doc/audit/ISSUES.md 与 .doc/ops/lessons/INDEX.md,核对当前源码后采纳:
|
||||
- LESSON-20260923-matrix-status-cas:文档状态与 CAS 收据不能因拆仓失效。
|
||||
- LESSON-20260924-cursor-hook-advisory-gates:客户端提示与硬门禁分层,不称 UI/本地 hook 足以保护远端。
|
||||
- LESSON-20260926-failclosed-bypass-contract:缺失组件/收据/权限失败关闭,禁止 gitlink 绕过。
|
||||
- LESSON-20260927-server-facts-and-iso-db-recipe:未来验证使用明确隔离 DB,不回退至真实 dev。
|
||||
- 当前 Squad step-empty-output、squad-commit-authority、quality-heading 相关台账按原状态保留;本轮不修复、不关闭。
|
||||
|
||||
这次没有实施与运行验证,不新增 validated 经验;多仓适配风险在本研究记录和计划出口追踪,进入实施后按对应失败事实建问题/回归记录。
|
||||
未修改共享 ISSUES/CURRENT/MATRIX,避免把待审架构建议写成现行缺陷修复/生效规范。
|
||||
|
||||
## Review Record
|
||||
|
||||
ce-plan 研究后,由 ce-doc-review 的一致性、可执行性、安全、范围、产品价值、反向挑战视角复核。
|
||||
本地审查的四项实际修订:
|
||||
1. 五分钟上游通知明确为后续自动化目标,首期检查点不伪称实现该 SLA。
|
||||
2. U1 只验基线/平台可行性,完整候选队列/回写恢复在 U2 实现后验收,消除前置依赖循环。
|
||||
3. 内部完整源码包与公开源码包分开;公开包采用允许清单,排除私有开发资料,并加入负例。
|
||||
4. U6a 提前从当前固定单仓基线交付私有包试点,U6b 在拆仓后复验同一构建合同。
|
||||
|
||||
补充跨模型检查曾通过 ce-doc-review 的 claude CLI 路线请求 claude-opus-5/high,对 security/product/adversarial/whole-doc 发起只读复核。四个任务在本地审查完成后仍未返回结果,主代理主动终止附加检查;runner 记录 timeout(reaped on request before completion),result 读取均返回 3、没有审查产物。未验证实际服务模型,未将其计为独立复核或 PASS。此限制不改变本地六视角的事实与修订记录。
|
||||
|
||||
本地审查汇总:coherence 1、feasibility 1、security 1、product 1 项已修订;scope/adversarial 没有追加有效问题。未对复用同一子代理上下文的后续角色作独立性加权。
|
||||
用户要求完整待审方案,允许对本轮草稿调整完善,四项修改均保持 Product Contract 与用户已确认边界;不存在需要以草稿修订为由提前实施的动作。
|
||||
|
||||
最终文档检查:三份 Markdown 的 frontmatter、代码围栏、相对链接、R1–R10/U1–U6/V1–V12 覆盖与 whitespace 检查通过;git diff --check 通过。实施测试均未运行。
|
||||
只读收口:agentctl cleanup report exit=0,19 worktrees,ready=0、blocked=19;没有删除。agentctl docs drift exit=0,30 records、regressions=0、open_capabilities=3;没有改 MATRIX。
|
||||
CodeGraph 在开始与收口运行 sync -q 成功;其近似索引仅辅助定位,依赖完整性以 rg 核对。
|
||||
这些是文档审查修订,不是系统已支持的能力。
|
||||
|
||||
## External References
|
||||
|
||||
- [Git submodule](https://git-scm.com/docs/git-submodule):固定提交、相对 URL 解析。
|
||||
- [Go 模块布局](https://go.dev/doc/modules/layout):internal 可见性与公开包。
|
||||
- [Go cgo](https://go.dev/cmd/cgo/):交叉编译与 C 工具链边界。
|
||||
- [Gitea Actions FAQ](https://docs.gitea.com/usage/actions/faq/):PR head 与合并候选区别。
|
||||
- [Gitea Actions token](https://docs.gitea.com/usage/actions/token-permissions/):fork 和跨仓权限。
|
||||
- [Gitea 保护分支](https://docs.gitea.com/usage/access-control/protected-branches/):审批与状态检查配置。
|
||||
- [Gitea 仓库权限](https://docs.gitea.com/1.22/usage/permissions/):私有仓访问语义;最终以实例 ACL 实测为准。
|
||||
|
||||
## Revision 2: Web and Agent-Native
|
||||
|
||||
授权来源:用户在原方案审阅中追加前端拆仓和 pi-native/agent-native 共享执行基础设计;沿用 task_id,不启动实施。
|
||||
本轮源码基线仍为 a3db288a7aa055ff5884e3aa4d91511959cff721,文档上一提交为 de90d0cd70e5cfadbd680e8caf8bdf18724e44a8。
|
||||
旧机器登记已 done,agentctl 不提供 reopen;新增同 worktree 的执行登记 multi-repo-design-2026-09-28-r2,逻辑任务和三个允许写路径不变。
|
||||
|
||||
### Confirmed Wiring
|
||||
|
||||
| 证据位置 | 确认的事实 |
|
||||
|---|---|
|
||||
| internal/agent/backend.go:38–60 | 公共 Backend/Execute,工厂支持 pi-agent/pi-native;native 包裹 PI fallback;未知名默认 Stub |
|
||||
| internal/app/app.go:132–133 | 通过同一工厂创建助手 dialogueBackend 并注入 coordinator |
|
||||
| internal/coordinator/dialogue_llm.go:126 | 助手调用 Execute,交付 reply.md;当前非直接返回文本接口 |
|
||||
| internal/squad/service.go:261、402 | Squad 任务/工作流也调用同一后端工厂 |
|
||||
| internal/config/config.go:109 | 源码默认 AGENT_BACKEND 为 pi-agent;不证明运行配置 |
|
||||
| internal/app/app.go:162–186 | 语义摘要、文档变更叙事、U9 segment 仍有 pi-agent 名称条件 |
|
||||
| internal/agent/pinative.go:17–28、96 | PiNativeBackend 是产品配置/工作区与 agentx.Run 的适配层 |
|
||||
| internal/agentx/loop.go | 具备原生 loop、tool 调度、stream、usage、turn cap;不是完整产品持久任务控制面 |
|
||||
| internal/agentx/llm/client.go:14 | 当前是兼容 Chat Completions 的 client,不能推断全供应商适配 |
|
||||
| internal/agentx/session/jsonl.go | 本地 JSONL transcript 与对象 mutex;不是跨进程执行租约 |
|
||||
| internal/agent/fallback.go:21–41 | native 不成功且 context 未取消时尝试 PI;Name 仍可为 pi-native,仅日志记录实际回退 |
|
||||
| internal/taskrun/backend.go | 另有后端名称 allowlist 和生产 stub 限制,改名需全入口一致 |
|
||||
| web/package.json / vite.config.ts | 独立 npm 构建、测试与 Vite API proxy,可作为独立源码仓 |
|
||||
| web/embed.go:14 | 当前 Go embed 与前端目录共置,不能直接整体搬走而不处理 Go import |
|
||||
| internal/server/static_assets.go:16、20–36、resolveDistDir | 导入主模块 web;磁盘资源优先,多个相对路径可能遮蔽内嵌 UI |
|
||||
| web/src/api/* / admin/console | 手写 API 客户端、auth header/cookie、后端信息展示需要契约与兼容检查 |
|
||||
|
||||
CodeGraph sync 成功并 explore PiNativeBackend;rg 再确认助手/Squad 工厂调用和 agentx import 依赖。
|
||||
未读取业务 output.md、workspace.json、模型密钥或运行实例环境;没有调用真实模型或产品 Agent。
|
||||
所以结论是“源码支持双方选择 native、具备公共接口”,不是“当前两条线上路径已运行 native”或“native 全能力已验收”。
|
||||
|
||||
### Revision Decisions
|
||||
|
||||
1. 新增 Agent-System-Web 与 Agent-Native 仓库建议;Core 不再承载前端源码和通用 Agent 内核。
|
||||
2. Agent-Native 包含 contract/runtime/adapters/conformance;公共 contract 不反向依赖 Core/Squad,Core 注入后端,Squad 只使用契约。
|
||||
3. 模型适配、完整 Agent 适配、工具适配分开;保留未来吸收先进实现的空间,不承诺任意 SDK/CLI 即插即用。
|
||||
4. pi-native 旧名、AGENTX 配置与 .agentx 数据路径提供兼容;默认后端不随拆仓切换。
|
||||
5. 区分 native 自身成功与 PI fallback 成功;未知副作用不自动跨后端重放。
|
||||
6. Web 构建产物在隔离构建上下文物化到 Core embed 目录,仍可发布一个包含 UI 的服务二进制;不提交 dist 或软链接越界。
|
||||
7. 增加 U7/U8、R11–R13、V13–V16,同步更新仓库地图、拓扑、Core/Squad 依赖、发布组合和描述;没有只追加一个与旧建议矛盾的附录。
|
||||
|
||||
### Revision Verification
|
||||
|
||||
本轮针对新增边界做源码/官方资料核对与作者一致性复核,不复用第一轮六视角结果作为修订 2 的新增审查证据;未发起额外外部模型复核。
|
||||
复核修正:U7a 先形成可独立获取的最小 contract 模块,U4 消费它,U7b 再迁 native/PI 实现,避免 Squad 和完整 Native 提取相互等待。
|
||||
Go embed 的包/模块边界据[官方文档](https://pkg.go.dev/embed)确认;Vite 独立构建/后端集成据[官方指南](https://vite.dev/guide/backend-integration)核对;工具与完整 Agent 的区别参考[MCP 架构](https://modelcontextprotocol.io/docs/learn/architecture)。
|
||||
仅实施计划中定义真实 native/PI、浏览器与平台验收,本轮未运行,不能标 PASS。
|
||||
|
||||
## Revision 3: Ubuntu-only and PI Core Parity
|
||||
|
||||
用户确认近期不需要 Ubuntu ARM/Apple Silicon;异步澄清确认目标为“对齐核心能力并逐步替代”,不是仅兼容接口或完整上游复刻。仍未授权实施。
|
||||
本机 uname -m=x86_64,os-release=Ubuntu 26.04.1 LTS;当前支持目标改为 linux/amd64,无需本期交叉编译。
|
||||
只读核对 deploy/pi-agent/Dockerfile 固定包0.85.1;npm 该版本元数据 gitHead=d981de1229ef899957bbe968bc8dcda02a21f477,repository=earendil-works/pi,license=MIT。通过内存读取发布tarball检查README/compaction/rpc/extensions文档,无安装/执行包代码;未验证运行容器版本。
|
||||
项目 pi-args 默认 --mode rpc --no-session,workspace 为受限工具且加载扩展;Runner提供 /v1/run 与 /v1/search,typed-result-v1 与 Tavily 属于实际依赖范围。
|
||||
agentx 已有 loop/tools/session/stream/steering/follow-up;没有因此推断完整 PI compaction/扩展/会话兼容。
|
||||
现有 abtest/Suite 只有6例;Judge比较成功率/P0/P95≤1.3倍;live测试直接 NewPiNativeBackend 禁止隐性fallback,RUN_AGENTX_AB=1 才运行。本轮未运行它,不把既有测试代码当通过证据。
|
||||
新增独立 U9 能力盘点→补齐→对比→渐进启用→替代收口;移除本期双平台要求、macOS签名阻断与ARM构建要求;更新描述与验收。
|
||||
来源:https://registry.npmjs.org/@earendil-works%2fpi-coding-agent/0.85.1 与固定提交的上游 README/docs;上游main仅用于导航,能力基线以固定版本为准。
|
||||
|
||||
## Revision 4: Governance Review
|
||||
|
||||
用户要求根据多仓/Ubuntu/Agent-Native方案复审锁、agentctl及规范,可在方案中删减不必要/频繁出问题的机制并补齐缺项。
|
||||
授权仍为研究和待审文档,不执行规范切换,不改变现行工具/配置/数据库/远端设置。
|
||||
|
||||
### Confirmed Issues and Evidence
|
||||
|
||||
ISSUE-20260928-governance-lock-domain,issue_state=investigating,owner=Codex(方案),影响为独立工作区无关写入被全仓恢复状态阻塞。
|
||||
已证实机制:scripts/agentctl.py:532–557 的 path 资源和 overlaps 没有工作区标识;path:. 覆盖所有相对路径。
|
||||
scripts/agentctl_console.py:186 为 integrate_prepare 获取 path:. + git:index + git:dev;:211–220 对合并失败尝试abort后仍标 recovery_required。
|
||||
scripts/agentctl.py:982–998 的持锁比较继续纳入 recovery_required,因此一个候选冲突/失败可能长期挡住不同worktree。
|
||||
本会话 r2 提交与 r3 文档写入实际均被同一 operation 拒绝;它不是仅根据代码猜测的风险。
|
||||
没有调查那个集成任务具体合并失败的底层原因,不能声称已经定位其全部根因。
|
||||
|
||||
问题类别还包括过度恢复升级:execute 在带 env/git:dev 的命令非零退出时统一需要恢复(agentctl.py:1145–1146);应按实际副作用证据区分,不能因此把真正未知结果直接释放。
|
||||
physical_names 将 git:dev 与 env:dev 绑定同一 dev-integration.lock;固定制品部署后可分离代码引用与运行环境锁。
|
||||
|
||||
另有 task 生命周期不一致:规范允许 blocked并要求原task_id续办,task close 只支持done/cancelled,register拒绝非active的同ID。
|
||||
本会话曾尝试blocked而被CLI明确拒绝;新增-r2/-r3只是受限工具下的执行登记,逻辑研究任务一直保持原ID。
|
||||
建议新工具原ID可reopen/update-state,执行尝试另有attempt_id,旧运行副作用日志保留。
|
||||
|
||||
治理快照(本轮只读SQLite URI mode=ro):completed=1455、failed=208、recovered=167、busy=21、recovery_required=1。
|
||||
其中recovered为command=144、integrate_prepare=22、integrate=1;这不是错误率、误报率或性能基准,不把正常恢复也算缺陷。
|
||||
阻塞operation为 integrate-nightly-advance-2026-09-28-r2-prepare-838577a7,resources含git:dev/path:./该候选tree,exit_code=1。
|
||||
稍后复核该记录已为recovered,本代理没有调用recover、删锁或修改管理数据库状态来解除它;正常agentctl with随后返回成功。
|
||||
Development-Manager中的对应overlaps/Lease/prepare与task close逻辑仍同类,不能靠只把工具搬仓根治。
|
||||
|
||||
### Decisions and Replacements
|
||||
|
||||
方案KTD6改用Gitea原生PR合并/保护/CI,取消默认自建签名收据网关、机器人直推与manually-merged回写。
|
||||
仍显式验证base/head/候选tree/组件manifest,合入后的真实SHA绑定制品和部署;不能将PR head测试当合并候选通过。
|
||||
方案KTD13给出retain/replace/remove矩阵、局部资源身份、known-failure/unknown分类、任务续办、清理和规范层级。
|
||||
U2负责替代治理与切换,补V19–V23负例;不是另外堆一套大型协调服务。
|
||||
工作区的源码副本不互锁;同实际目录和共享环境保留适用保护;产品数据库事务/文档职责/运行租约不在工程锁裁剪范围。
|
||||
|
||||
暂不修改共享ISSUES/lessons索引:本次用户明确仅允许三个待审文档,本节保存问题主记录候选,实施/正式文档集成时由相应owner补索引。
|
||||
没有修复和回归运行,不把上述问题标resolved或经验标validated;既有coordination-authority问题继续按原状态追踪。
|
||||
|
||||
### Authority and Exception Record
|
||||
|
||||
曾因正常入口仍被全仓恢复锁阻塞,请求只针对这三份文档的临时租约豁免。
|
||||
用户批准:owner=Codex,原因=待审文档落盘被无关恢复操作阻塞,覆盖=本任务三文档的agentctl with前置,禁止=解锁/改工具或现行规范/提交/推送;有效期=保存完成即结束;恢复动作=保留可审diff,恢复正常租约流程。
|
||||
实际结果:原阻塞先恢复,r3与r4方案主体通过agentctl with保存;随后新操作integrate-nightly-advance-automation-2026-09-28-r7-prepare-dca474ad再次进入recovery_required,正常入口拒绝最后的文档写入。
|
||||
本轮最后保存使用用户已批准的豁免,仅对原三文档直接写入;没有调用recover、删除锁、修改hook/agentctl/现行规范或提交/推送。完成保存和校验即终止豁免,后续回归正常租约流程。
|
||||
用户确认的“仅三份待审文档、不提交或推送”作为本次交付限制保留。
|
||||
|
||||
修订3的Ubuntu单平台和U9原生核心替代已经本轮正常落盘;修订2工作区改动一并保留,没有丢弃或覆盖其他任务文件。
|
||||
本次审查是源码/运行元数据/官方Gitea资料的定向核对与作者一致性检查,未声称重复进行了首轮六视角或外部模型审查。
|
||||
|
||||
最终校验:3份文档、6个相对链接、15项要求、9个实施单元、23项验收场景,结构/ID/链接/旧方案残留检查通过;git diff --check exit=0。收口盘点cleanup total=18/blocked=18/ready=0,未清理;docs drift regressions=0/open_capabilities=3。没有实施、编译或真实运行验收。本轮使用的一次性三文档豁免至此结束,不提交/不推送。
|
||||
|
||||
## Revision 5: Proportionate Everyday Rules
|
||||
|
||||
用户追加“很多规范过严,按最新方案适当完善”;本轮仍仅修订原方案、证据与任务,不批准或启用新规范。
|
||||
读当前AGENTS、PROJECT、验证契约、经验闭环、收口模板及KTD13;核实已有纯文档免全量测试/按机制选场景/矩阵按声明更新等合理条款,未把它们误报为全都缺失。
|
||||
|
||||
问题是执行尺度和入口一致性:Go/接口验证矩阵列全包vet/short,而报告章节又说明不无条件全量;需明确本地迭代/组件CI/组合发布三个检查阶段。
|
||||
启动阅读、每次收口盘点、任务与多表状态、逐修复lesson要求,对小改动容易叠加成本;应区分硬边界、默认做法和工具建议。
|
||||
本会话没有测试耗时/误报率统计,不虚构量化收益;提出的改进以规则文本和已出现流程阻塞为依据。
|
||||
保留真实权限、持久性、运行制品、敏感数据和已确认外部副作用边界。
|
||||
|
||||
新增KTD14及验证分层/证据复用/规则强度说明,扩展U2的规范模板同步和日常演练,新增R16/V24/V25。
|
||||
不新增implementation unit或独立报告,避免为了精简流程再扩大产物层级。
|
||||
本轮仅修订三文档,使用新的r5执行登记承载同一个逻辑task_id;上一轮一次性豁免已结束,本轮不自动沿用。
|
||||
|
||||
修订5验证:三文档结构、6个相对链接、R1–R16/U1–U9/V1–V25唯一性与待审状态检查通过,git diff --check通过。只读cleanup为18项blocked、0项ready,docs drift无回退;未清理工作区。正常agentctl with写入,无需也未沿用上轮临时豁免;未提交、推送、修改生效规范或执行产品测试。
|
||||
|
||||
## Revision 6: Remove Coding Workflow Dependence
|
||||
|
||||
用户明确反馈Agent主要精力被agentctl任务领取、提交、合并消耗。本轮收敛KTD13/14的职责,新增KTD15:普通编码流程零agentctl依赖,任务/PR单一状态来源;治理恢复归维护者,发布部署独立。
|
||||
这不是已经测得时间占比;依据为用户观察与本会话两次跨工作区锁阻塞、登记续办及blocked CLI不匹配的实际记录。
|
||||
修改U2优先顺序,先完成本地减负与Gitea交接,再做多仓适配;不把新的task/reopen/claim平台作为减负前提。新增V26端到端日常流程验收。
|
||||
本轮仅修订原三份待审文档,不启用新规则,不提交/推送;现行登记仍按当前工具执行,逻辑task_id未变。
|
||||
|
||||
## Revision 7: Single Executable, Instance Configuration and Native Infrastructure
|
||||
|
||||
用户连续补充:同一套单文件应用供测试/生产等多个实例,通过启动配置隔离;希望.env、CLI、系统设置后读覆盖;进一步评估KB/DB/文档库用launcher、daemon、应用内启动或原生程序。
|
||||
本轮作为原任务续办,只完善原三文档;此前中断段只读检查已完成,没有启动或变更产品服务。
|
||||
|
||||
### Baseline and Current Source Checks
|
||||
|
||||
原研究worktree仍HEAD=de90d0cd(业务源码基线a3db288a);主目录本轮已为test@fd177f8dd5c7e5714476b59efc1b9a2ae27bdb22,dev=b9339cd27206f519f423eaa6a1601d3a67dfac01。
|
||||
没有切换/重置主目录或重新合并业务源码。
|
||||
对a3db288a..dev的config/localpg/sysadmin settings/db migrate/main/app/templates/web embed/build-single-binary以及kb/storage/workspace/docrevision相关路径做diff --stat,无差异输出;本节结论同时适用于本轮核对的这些dev路径,不能推及未查模块或运行环境。
|
||||
没有读取.env真实值、用户output.md、workspace.json、运行数据库数据或修改系统设置。
|
||||
|
||||
### Source Findings
|
||||
|
||||
| 来源 | 已确认事实与影响 |
|
||||
|---|---|
|
||||
| cmd/server/main.go:22–40、config/config.go:103、159–174 | 默认→env文件→进程env,CLI只覆盖env/port/host/backend;默认.env路径与Load空字符串的overlay路径不同 |
|
||||
| config/config.go:99、localpg/localpg.go:36/48/74 | 存在dev默认路径与部分直接os.Getenv读取;尚非统一最终配置快照 |
|
||||
| sysadmin/settings.go:78/229/275 | 独立DB→进程env→默认解析,不直接消费已合并CLI/.env的cfg;不能说所有系统设置已整体覆盖启动配置 |
|
||||
| sysadmin/service.go:NewService、settings/store | 系统设置来自所选业务PG,key无实例命名空间;用它配置自身连接会循环 |
|
||||
| sysadmin/apply.go、settings.go:199、app/app.go | 部分键推送PI /admin/reload;保存、热更新和真正启动消费并不等价 |
|
||||
| db/migrate.go:RunMigrations/ResolveMigrationsDir | 当前Goose从磁盘SQL目录读取;现有二进制尚未内嵌全部迁移 |
|
||||
| web/embed.go、templates/embed.go、template/loader.go、squad/service.go | Web与部分Markdown已内嵌,agent指令和xlsx等仍依赖磁盘路径 |
|
||||
| localpg/localpg.go:100/123/271/287 | 查找已安装PG→可initdb建cluster→createdb建应用库→启用vector;不是安装数据库,也不创建独立KB语料库 |
|
||||
| localpg/localpg.go:187/261/307、cmd/server/main.go | 当前按端口就绪判断、已有角色bootstrap、started标记与defer清理不足以证明所有权/崩溃恢复;os.Exit可绕过defer |
|
||||
| kb/client.go:75/94、kb/store.go、kb/embed.go | KB是应用内检索代码直连PG;embedding/reranker为外部HTTP能力;连通不等于语料与索引已准备 |
|
||||
| storage/cas.go:42、workspace/capability.go、docrevision/pg_store.go | 文档库由PG账本/内容与持久文件组成,非独立文档daemon |
|
||||
| app/app.go:224、workspace/lease.go | 进程内workspace租约不足以宣称多副本共享同一数据根已安全;独立实例与HA副本分开 |
|
||||
| cmd/server/main.go:71、cmd/events/main.go | server已有可选内置events consumer,单文件模式可收敛到同一程序角色,不必分发第二个应用程序 |
|
||||
|
||||
两项后续调查候选:配置解析双路径/生效声明不一致、managed-local PG所有权与失败回收不足。
|
||||
本轮没有运行复现或修复,不登记为resolved,不改共享ISSUES索引;U10中给出针对性正负例。
|
||||
既有data-dir-doubled、PI runner DATA_DIR覆盖、隔离DB经验直接用于路径归一化与禁止隐式dev回退的验收设计。
|
||||
|
||||
### Decisions
|
||||
|
||||
1. 单版本单个Ubuntu amd64应用文件内置Web/SQL/prompts/xlsx等资产,同文件可启动多个独立实例;配置/数据/日志不打进程序。
|
||||
2. 不新增应用launcher/KB/文档daemon;同一二进制提供serve/init/migrate/config检查,系统服务管理应用和原生PG。
|
||||
3. 产品部署设置放独立实例配置根的instance-settings文件,作为普通部署参数的最终层;产品业务策略仍在所选DB,key各有唯一owner。
|
||||
4. bootstrap identity/config_root/settings读取模式不自覆盖;DB/KB/目录等可经UI配置,但须重启/迁移后确认applied,不能在进行中任务里换一半。
|
||||
5. 默认existing;显式创建逻辑库与安装PG/建立cluster/迁移schema/导入KB区分;managed-local仅可选自有cluster。
|
||||
6. 配置身份、DB角色、可写目录、cookie/密钥、Runner上下文和文件/数据库备份同时隔离;一套二进制不构成隔离证明。
|
||||
7. U10为应用部署新工作,U6a要先满足其最小单文件/外部PG出口;不把该需求隐藏在U9的PI能力替代里。
|
||||
|
||||
复核由独立只读子审查覆盖配置链、存储/进程依赖与设计一致性,补齐saved/applied、最终配置冲突检查和外部进程停止权。
|
||||
本轮没有额外外部模型审查、编译、initdb、建库、启动/停止daemon、服务配置写入或业务数据迁移。
|
||||
|
||||
### Primary References
|
||||
|
||||
- [PostgreSQL initdb](https://www.postgresql.org/docs/current/app-initdb.html):cluster初始化与原生进程身份。
|
||||
- [CREATE DATABASE](https://www.postgresql.org/docs/current/sql-createdatabase.html):逻辑数据库创建。
|
||||
- [PostgreSQL启动与系统服务](https://www.postgresql.org/docs/current/server-start.html):原生postgres/pg_ctl和系统服务职责。
|
||||
- [pg_ctl](https://www.postgresql.org/docs/current/app-pg-ctl.html):原生管理边界。
|
||||
- [pgvector项目](https://github.com/pgvector/pgvector):PG内扩展而非单独daemon。
|
||||
systemd官方man页面本次抓取403,未将该失败当作成功资料;系统服务建议参考PostgreSQL官方启动文档。
|
||||
|
||||
修订7验证:3文档结构、6个相对链接、R1–R19/U1–U10/V1–V34唯一性与待审标记检查通过,git diff --check通过;只读cleanup为20项blocked/0项ready,docs drift无回退,未清理。源码/配置/生命周期定向复核完成;未编译、建库、运行实例或部署。文档通过正常agentctl with保存,本次未使用临时豁免,仍不提交/不推送。
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: "U1 治理演练记录:Gitea 原生门禁与 CI 可用性验证"
|
||||
date: 2026-09-29
|
||||
task_id: multi-repo-design-2026-09-28
|
||||
drill_repo: weichen/governance-drill-2026-09 (private, 验证后保留至 U2b 收口再删)
|
||||
basis: 2026-09-29-multi-repo-implementation-plan.md Phase 0 / U1.5
|
||||
---
|
||||
|
||||
# U1.5 演练结论(全部通过)
|
||||
|
||||
环境:Gitea 1.27.3(本机 docker:gitea-server/gitea-db/gitea-runner),runner `home-runner`,
|
||||
标签映射:`ubuntu-latest→docker://gitea/runner-images:ubuntu-latest`、`docker→docker://docker:dind`(不可用)、`nightly→host`。
|
||||
|
||||
## 分支保护与 PR 门禁(负例 + 正例)
|
||||
|
||||
保护配置(drill main):enable_push=false、required_approvals=1、dismiss_stale_approvals=true、
|
||||
block_on_outdated_branch=true、apply_to_admins=true、status_check_contexts=[pr-verify / verify (pull_request)]。
|
||||
|
||||
| 编号 | 场景 | 结果 |
|
||||
|---|---|---|
|
||||
| N1 | admin 身份 HTTP 直推保护分支 | 拒绝(pre-receive hook declined;apply_to_admins=true 生效) |
|
||||
| N2 | API PUT /contents 写保护分支 | 拒绝(user cannot commit to repo) |
|
||||
| N3 | 无批准合并 PR | 拒绝(Does not have enough approvals) |
|
||||
| N4 | 批准后 head 新提交再合并 | 拒绝(陈旧批准被撤销);重新批准后可合并 |
|
||||
| N5 | required status check 未完成时合并 | 拒绝(405 Please try again later);CI success 后合并成功 |
|
||||
| 自批准 | 作者批准自己的 PR | **Gitea 1.27.3 硬禁止**(approve your own pull is not allowed),admin 亦不可 |
|
||||
|
||||
合并语义:merge 后 base.sha=merge_commit_sha(0540e27c),merged_by=审核者(weichen)而非作者。
|
||||
PR #2/#3 全流程:agent-bot(作者)→ weichen(批准+合并),作者/审核者分离经 Gitea 原生强制。
|
||||
|
||||
## D2' 决策修正:agent-bot 机器账号
|
||||
|
||||
单账号下 required_approvals=1 永远无法满足(自批准被硬禁止)。
|
||||
已创建机器账号 `agent-bot`(凭据存 `~/.secrets/agent-bot`,token scope:write:repository, read:user):
|
||||
编码 Agent 以 agent-bot 提交/建 PR;用户以 weichen 批准并合并。原方案 D2"不建机器人账号"据此作废。
|
||||
|
||||
## CI 可用性与根因修复
|
||||
|
||||
发现并修复 Agent-System CI 自 2026-09-24 起全红的根因:
|
||||
|
||||
1. **docker 网络地址池耗尽**:历史 CI 任务遗留 24 个 `GITEA-ACTIONS-TASK-*` 桥接网络未清理,
|
||||
默认地址池(~16 个 /16 池)占满,此后所有 docker 模式任务创建 job 网络时报
|
||||
`all predefined address pools have been fully subnetted` 秒败。已清理全部 24 个陈旧网络(10 个网络保留),
|
||||
清理后 ubuntu-latest docker 模式任务验证成功。
|
||||
2. **nightly host 模式失败为当时环境问题**:09-24~28 日志显示 runner 容器内 github.com DNS(fake-ip 198.18.0.1)拒绝;
|
||||
当前 DNS(192.168.3.1)下 runner 容器可访问 github.com,`actions/checkout@v4` 克隆探针成功。
|
||||
3. `docker:dind` 标签的镜像拉取在本机挂死,该标签不可用;工作流避免使用。
|
||||
|
||||
## Workflow 路径行为(实例特性)
|
||||
|
||||
- **新仓库只有 `.gitea/workflows/` 路径触发**(树级检测:文件未被本次提交修改也会触发);
|
||||
drill 仓 `.github/workflows/` 从未触发(含文件被修改的推送)。
|
||||
- 存量 Agent-System 仓 `.github/workflows/` 正常触发(run 74 = 本日 dev 推送,179 个历史任务均来自该路径)。
|
||||
- 结论:现有 Agent-System 维持 `.github/workflows/` 不迁移;**新建仓库一律用 `.gitea/workflows/`**。
|
||||
实例对不同仓库的路径检测差异根因未深究,已记录为已知行为。
|
||||
|
||||
## 遗留状态
|
||||
|
||||
- drill 仓任务 183/185(docker:dind 拉取挂死)在 UI 呈 running 僵尸态,无实际执行,仓库删除时一并消失。
|
||||
- 演练仓保留至 U2b 完成(作为保护配置参照),之后删除。
|
||||
|
||||
## 对 U2b 的直接输入
|
||||
|
||||
- dev/test/main 保护字段组合与白名单保底方案(weichen 进 push whitelist 以不破坏现有直推流程)。
|
||||
- required checks 的 context 命名格式:`<workflow> / <job> (<event>)`。
|
||||
- 新流程红线:作者≠批准者由 Gitea 强制;Agent 不得以 weichen 身份批准自己的 PR。
|
||||
@@ -13,6 +13,22 @@
|
||||
|
||||
## 核心文档(按阅读顺序推荐)
|
||||
|
||||
### 系统全面 Code Review(2026-09-26)
|
||||
|
||||
**文件**: [2026-09-26-system-code-review.md](./2026-09-26-system-code-review.md)
|
||||
|
||||
**结论**: tip `f4c1b73f` 上 `arch-check --mode block` PASS,但存在已证实会话上下文 IDOR、arch-check 未登记表静默跳过、Authorizer 无池 fail-open、swboot `sh -c` 前缀白名单、intentflow `proposed` 可 Confirm 升 dispatch 等 critical/high 项;FAV outbox 禁用路径未见旁路。**本轮不实施修复**。
|
||||
|
||||
**任务**: [short-term](../ops/short-term/2026-09-26-system-code-review.md) · mutex `docs-audit-review`
|
||||
|
||||
### 对话办公能力全景盘点(2026-09-25)
|
||||
|
||||
**文件**: [2026-09-25-dialogue-office-capability-research.md](./2026-09-25-dialogue-office-capability-research.md)
|
||||
|
||||
**结论**: 32 ActionKey 双轨脱节(主链假成功 vs intentflow 部分 live);HTTP 169 = A46/B66/C44+基线13;治理结构写永久 UI 专属。整改见 P0–P3 计划。
|
||||
|
||||
**整改**: [对话办公扩展计划](../remediation/2026-09-25-dialogue-office-expansion-plan.md) · task `dialogue-office-expansion-2026-09-25`
|
||||
|
||||
### 模块化重构方案审核检查清单(2026-09-23)
|
||||
|
||||
**文件**: [2026-09-23-modular-refactor-plan-review-checklist.md](./2026-09-23-modular-refactor-plan-review-checklist.md)
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
# 问题与修复台账
|
||||
|
||||
维护规则:[问题记录与开发经验闭环](../ops/2026-09-23-issue-learning-workflow.md)。每个问题一个稳定 ID;主记录是事实与状态来源,本表为可检索投影。新发现及时登记,修复后保留记录;发布 blocker 仍见 [gap-matrix](../remediation/gap-matrix.md)。
|
||||
|
||||
更新:2026-09-28。资料类名词提问被识别成模糊咨询并吃到阶段推销模板(resolved:intent-material 已合入修复与验收报告);阶段推进失败后没有助手消息(open,未修)。docgov 共享 map 并发读写曾在 06:38 UTC 打崩 dev 进程(resolved:dev `b9339cd2` 重建后 `/health` 200,空登录 401)。只上传文档、无文字时对话 400 已在重载后的 dev 浏览器复验(resolved,`bin/agent-server` 10:22 +0800)。历史任务 run 事件流 HTTP/2 与 502 另记,未在本轮修。激活预览前端预检与管理台密钥 form 已在 dev 浏览器复验(resolved,dev `3e534bbb`,项目 6023)。非编制人触发小队账本提交被 `uow: permission denied` 拒绝,已改为编制人代理提交并在 dev 重跑通过(resolved)。test 注册 INTERNAL:标准角色 role-guest 缺失导致 FK 23503,已补种并重启 test(goose 77,resolved)。重复用户名 400 在新代码单测通过;当前 rc 二进制仍返回 INTERNAL,随下次含本提交的 test 制品生效。管理台重置密码入口被 F4-A 误删(端点仍在),已恢复 UI(resolved)。2026-09-27。上传链路:登记并修复上传文档跨端不可访问(占位模板退化 + 元数据/正文不落服务端,fixing 待 dev 集成)。2026-09-26。docgov 批准链:登记并修复 review_snapshot_id 装载缺失与 uow 行锁自死锁(resolved);memDocs 持久化失败缓存投毒(investigating)。历史 resolved 不表示本日产品回归通过。系统 code review P0/P1 批次修复落账(5 resolved + 1 deferred + 1 open,主记录见 [整改文档](2026-09-26-system-code-review-fixes.md),来源 [审计](2026-09-26-system-code-review.md))。
|
||||
|
||||
| issue_id | 模块 / 检索词 | 问题 | 严重度 | issue_state | owner | 证据日期 / 范围 | 唯一主记录 | 经验 |
|
||||
|---|---|---|---|---|---|---|---|---|
|
||||
| ISSUE-20260928-material-template-reply | intent / coordinator / 说明书 / 操作视频 / 掂量 / reply_source=template / fallback_reason | 说明书、操作视频、竞品等资料名词未进知识词典,落到模糊咨询后输出阶段推销模板;对话模型失败时没有日志和 fallback 原因 | high | verifying | Cursor | 2026-09-28;test 会话 sess-p8-u33;dev 库项目 6024 工作树二进制 reply_source=kb | [主记录](../ops/short-term/2026-09-28-intent-material-fallback.md#issue-20260928-material-template-reply) | [LESSON-20260928-material-noun-not-sales-template](../ops/lessons/2026-09-28-material-noun-not-sales-template.md) |
|
||||
| ISSUE-20260928-advance-stage-silent-fail | coordinator / ADVANCE_STAGE / EXPECTATION_HIT / step_03_regulatory / chat turn failed | 用户回复「1」触发阶段推进后,法规步骤失败,回合被标失败且没有助手消息,用户盲等 | high | open | Cursor | 2026-09-28;test 会话 sess-p5-u32 turn 22;本轮只登记不修 | [主记录](../ops/short-term/2026-09-28-intent-material-fallback.md#issue-20260928-advance-stage-silent-fail) | 未修,不新增经验 |
|
||||
| ISSUE-20260928-docgov-map-race | docgov / memDocs / concurrent map / GetDocument / 登录 500 | per-doc 锁拆分后共享 map 无互斥,不同文档并发读写 fatal,进程退出期间全部 API 500 | critical | resolved | Cursor | 2026-09-28;fatal + ECONNREFUSED;`-race` PASS;dev `b9339cd2` 重启后 `/health` 200、空登录 401(`req_e28309cc8d615ed4`)、Vite public-config 200 | [主记录](../ops/short-term/2026-09-28-docgov-shared-map-race.md#issue-20260928-docgov-map-race) | [LESSON-20260928-docgov-shared-map-race](../ops/lessons/2026-09-28-docgov-shared-map-race.md) |
|
||||
| ISSUE-20260928-quality-heading-drift | squad / quality_gate / 缺少必填章节 / State-of-the-Art / H3 | 调研报告章节在,只因 H3 和少空格被判缺章,受控文档不投影 | high | resolved | Cursor | 2026-09-28;dev `bd_research_1790578240073269711` project_id 6024,quality passed,doc head_snapshot_id 62 | [主记录](../ops/short-term/2026-09-28-quality-gate-heading-mismatch.md#issue-20260928-quality-heading-drift) | [LESSON-20260928-quality-heading-normalize](../ops/lessons/2026-09-28-quality-heading-normalize.md) |
|
||||
| ISSUE-20260928-data-dir-doubled | workspace / data/dev/data/dev / DataDir | 出现双层 `data/dev/data/dev/workspaces` 且只有孤立 output.md,写入点未证实 | medium | open | — | 2026-09-28;`intake_1790565513115586191` 双路径对照 | [主记录](../ops/short-term/2026-09-28-quality-gate-heading-mismatch.md#issue-20260928-data-dir-doubled) | 本轮不修 |
|
||||
| ISSUE-20260928-progress-query-trigger | intent / matchTriggerTask / QUERY_PROGRESS / 编写进度 | 询问调研报告编写进度时,写动词加任务名词被识别成启动新任务,进度回复不读真实 run | medium | verifying | Cursor | 2026-09-28;「调研报告编写进度怎么样了」单测为 QUERY_PROGRESS;「开始做调研报告」仍为 research。浏览器复验见测试报告 | [主记录](../ops/short-term/2026-09-28-refresh-task-state-recovery.md) | 疑问进度句必须让行查询;显式「开始/重新」仍启动任务 |
|
||||
| ISSUE-20260928-step-empty-output | squad / stepOutputAccepted / output_digest / e3b0c442 / MaterializeTargets | 步骤已把正文写到 output.md,判定仍因 runner Success=false 或空 patch 记空输出失败 | high | verifying | Cursor | 2026-09-28;11:27 `research_1790566028724181453` 的 06_draft 盘上 41KB 但 digest 为空;单测覆盖缺交付物但盘上有正文,以及连接错误仍失败关闭 | [主记录](../ops/short-term/2026-09-28-refresh-task-state-recovery.md) | 传输/可重试失败留下的文件可能是截断的,不能当成功;缺交付物且盘上非空才接受 |
|
||||
| ISSUE-20260928-task-write-verb | intent / hasTaskWriteVerb / 帮我定 / 制定 / AMBIGUOUS_FALLBACK | 「帮我定/制定」设计开发计划任务书未进入任务触发,对话只有掂量阶段模板 | medium | resolved | Cursor | 2026-09-28;test sess-p8-u33 msg 89/90;意图单测 | [主记录](../ops/short-term/2026-09-28-test-user-doc-issues.md) | [LESSON-20260928-task-write-verb-visible-refusal](../ops/lessons/2026-09-28-task-write-verb-visible-refusal.md) |
|
||||
| ISSUE-20260928-workflow-scope-reply | coordinator / ClarificationQuestion / ErrPrerequisiteNotMet / rd_design_plan | 跨工作流澄清与研发前置未满足时,原因没有进入对话 | medium | resolved | Cursor | 2026-09-28;协调器单测。test 原例停在动词未命中,未走到本分支 | [主记录](../ops/short-term/2026-09-28-test-user-doc-issues.md) | [LESSON-20260928-task-write-verb-visible-refusal](../ops/lessons/2026-09-28-task-write-verb-visible-refusal.md) |
|
||||
| ISSUE-20260928-quality-failed-success-copy | bizdev / quality_failed / 正文已保存至 / output.md | 质量未通过仍声称正文已保存,并写出工作区绝对路径 | medium | resolved | Cursor | 2026-09-28;test cdo_quote_1790560155851280170;同步回复单测 | [主记录](../ops/short-term/2026-09-28-test-user-doc-issues.md) | [LESSON-20260928-task-write-verb-visible-refusal](../ops/lessons/2026-09-28-task-write-verb-visible-refusal.md) |
|
||||
| ISSUE-20260928-pi-runner-data-dir | agent / PI runner / DATA_DIR / MISSING_TARGET / 18866 | test 启动时根 .env 的 dev runner 地址盖过本环境 sidecar,工作区被重写到空目录 | high | resolved | Cursor | 2026-09-28;dev `4f581306`。当时 test 二进制仍是修复前制品 | [验收报告](../test-reports/2026-09-28-pi-runner-env-mismatch-test-report.md) | — |
|
||||
| ISSUE-20260928-material-chunk-embed | knowledge / chunk index failed / 8192 / 34635 tokens | 材料分块批超过嵌入模型上下文,索引失败 | medium | open | — | 2026-09-28;test 日志 project 8,文件 W020251117353305579317.docx | [主记录](../ops/short-term/2026-09-28-test-user-doc-issues.md) | 本轮不修 |
|
||||
| ISSUE-20260928-attachment-only-turn | chat / chat/stream / message cannot be empty / HTTP_400 / attachments | 只上传文档、不输入文字时 turn 被空消息 400 拒绝,前端不读信封,用户看不到任何回复 | high | resolved | Cursor | 2026-09-28;dev :8080 重载后浏览器仅附件得到梳理审阅,无关文字先回答再追问;pending 分支 API 200 | [主记录](../ops/short-term/2026-09-28-attachment-only-turn.md) | 空消息门禁要放在附件判定之后;4xx 必须读信封。见[测试报告](../test-reports/2026-09-28-attachment-only-turn-test-report.md) |
|
||||
| ISSUE-20260928-task-run-replay-502 | web / useRecoveredTaskPhases / tasks/runs / ERR_HTTP2_PROTOCOL_ERROR / 502 | 历史失败气泡恢复订阅 task run 事件时出现 HTTP/2 协议错误和 502,与附件空消息 400 无因果关系 | medium | verifying | Cursor | 2026-09-28;终态重放改为最多 4 次退避,401/404 立即停止;进行中订阅外层只再补 1 次,避免和内部 40 次重试相乘。尚未在真实 502 上复验 | [主记录](../ops/short-term/2026-09-28-refresh-task-state-recovery.md) | 重放失败要可重试;鉴权与不存在不要空转 |
|
||||
| ISSUE-20260928-activation-preview-precheck | web / projectSettings / activation-preview / NO_GOVERNED_DOCUMENT / clientDutyIssues | 全部文档未纳入人工审批时前端仍 POST activation-preview,控制台 400 | medium | resolved | Cursor | 2026-09-28;dev 项目 6023 默认计划无 activation-preview 请求,兼任后 preview 200 | [主记录](../ops/short-term/2026-09-28-activation-preview-precheck.md#issue-20260928-activation-preview-precheck) | [LESSON-20260928-activation-preview-client-gate](../ops/lessons/2026-09-28-activation-preview-client-gate.md) |
|
||||
| ISSUE-20260928-admin-secret-password-form | web / EnvSettingsSection / password / form / secrets | 管理台 5 个密钥输入不在 form 内,Chromium 报 password DOM 警告 | low | resolved | Cursor | 2026-09-28;dev 模型与密钥页 passwordInputs=5 outsideForm=0 | [主记录](../ops/short-term/2026-09-28-activation-preview-precheck.md#issue-20260928-admin-secret-password-form) | 密码框放进 form;autocomplete 不能单独消除该 DOM 警告 |
|
||||
| ISSUE-20260928-squad-commit-authority | bizdev / docflow / dutyAuthorizer / uow permission denied / OnBehalfOf / bd_intake | 非编制人触发受控小队任务时,账本提交用触发者身份,被编制人职责门拒绝,正文无法落盘 | high | resolved | Cursor | 2026-09-28;dev `b1ed8ecf` 重跑 `run_1790559088975684237` completed,commit actor 4,snapshot actor 74 | [主记录](../ops/short-term/2026-09-28-squad-commit-authority.md#issue-20260928-squad-commit-authority) | [LESSON-20260928-squad-commit-as-author](../ops/lessons/2026-09-28-squad-commit-as-author.md) || ISSUE-20260928-register-internal | auth / register / role-guest / system_roles / 23503 / 23505 / INTERNAL | test 缺 role-guest 时注册 FK 失败被脱敏为 INTERNAL;重复用户名唯一冲突同样 500 | high | resolved | Cursor | 2026-09-28;test:8081 补种并重启后注册 200(goose 77,req_regfix_after_restart);重复用户名 400 由单测覆盖,rc 二进制仍为 INTERNAL | [主记录](../ops/short-term/2026-09-28-auth-register-internal.md#issue-20260928-register-internal) | [LESSON-20260928-standard-role-reseed](../ops/lessons/2026-09-28-standard-role-reseed.md) |
|
||||
| ISSUE-20260928-admin-reset-ui-removed | web / UsersSection / 重置密码 / F4-A / adminResetPassword | F4-A 在 F4-B 端点已合入的基线上删除管理台重置密码按钮,管理员无法重置口令 | high | resolved | Cursor | 2026-09-28;dev API :8080 + worktree Vite :3110 真实 UI 探针 PASS(临时口令长度 16、强制改密仅一次、旧口令 401) | [主记录](../ops/short-term/2026-09-28-restore-admin-password-reset.md#issue-20260928-admin-reset-ui-removed) | [LESSON-20260928-ui-dead-control](../ops/lessons/2026-09-28-ui-dead-control.md) |
|
||||
| ISSUE-20260927-upload-doc-cross-device | freedoc / upload / freeform / fileMeta / 占位模板 / 跨端 | 上传文档源文件元数据与正文不落服务端:换浏览器/清存储/共享他人查看时退化为注册占位模板,文本类连二进制都未存(伴生 <512B 显示 "0 KB") | high | resolved | pi | 2026-09-27;dev `86efba2c` 合入并在 dev 环境验证:FS-UPLOAD-01/02 真实浏览器 PASS(跨上下文可见真实正文),DB 核验元数据+asset 落库;存量无元数据旧文档不可恢复(重新上传即可) | [主记录](../ops/short-term/2026-09-27-upload-doc-access.md) | [LESSON-20260927-server-facts-and-iso-db-recipe](../ops/lessons/2026-09-27-server-facts-and-iso-db-recipe.md) |
|
||||
| ISSUE-20260923-nullable-duty | docgov / nullable / 23503 / reviewer_id | 可选职责空值写 0 导致 FK 失败 | high | resolved | Codex(历史补录) | 2026-09-17;历史 PG / API 冒烟;当前未复测 | [主记录](2026-09-23-historical-issue-records.md#nullable-duty) | [LESSON-20260923-nullable-duty](../ops/lessons/2026-09-23-nullable-duty.md) |
|
||||
| ISSUE-20260923-content-hash | docrevision / canonicalize / hard-break / 404 | 规范化破坏 Markdown 语义并造成正文哈希漂移 | critical | resolved | Codex(历史补录) | 2026-09-14;历史真实 UI / 重启;当前未复测 | [主记录](2026-09-23-historical-issue-records.md#content-hash) | [LESSON-20260923-content-hash](../ops/lessons/2026-09-23-content-hash.md) |
|
||||
| ISSUE-20260923-coordination-authority | agentctl / claim / SQLite / CAS / CURRENT / FEATURE-MATRIX | 本地副本 CAS 与任务许可不能表达跨主机全局权威认领 | high | investigating | Codex(研究) | 2026-09-23;源码/只读状态,未复现具体丢写 | [主记录](../ops/short-term/2026-09-23-coordination-db-daemon-research.md#issue-20260923-coordination-authority) | 沿用 content-hash 投影经验;跨机结论待实施验证 |
|
||||
| ISSUE-20260923-matrix-status-regression | FEATURE-MATRIX / module-batches-ag / merge / docs-apply | 矩阵行 done 被 closeout 合并冲突手解回退为 planned | high | resolved | Cursor | 2026-09-23;本机 tip 与 git 考古;docs apply 已恢复 | [主记录](2026-09-23-matrix-status-regression.md) | [LESSON-20260923-matrix-status-cas](../ops/lessons/2026-09-23-matrix-status-cas.md) |
|
||||
| ISSUE-20260924-admin-reset-dead | auth / adminResetPassword / T20-F4 / chenwei | 管理台重置密码死按钮;验收口令不可知后无法恢复 | high | resolved | Cursor | 2026-09-24;test 库实查 + API 单测 | [主记录](2026-09-24-admin-password-reset-issues.md#issue-20260924-admin-reset-dead) | 待补 LESSON |
|
||||
| ISSUE-20260924-login-error-envelope | auth / AUTHZ / 无权访问 / auth.ts | 登录失败展示裸 JSON / 「无权访问」误导 | medium | resolved | Cursor | 2026-09-24;wire 复现 + 前端单测 | [主记录](2026-09-24-admin-password-reset-issues.md#issue-20260924-login-error-envelope) | 待补 LESSON |
|
||||
| ISSUE-20260924-zombie-credentials | auth / user_credentials / LEFT JOIN / CreateUser | 空哈希静默建号导致永久无法登录 | high | resolved | Cursor | 2026-09-24;三环境只读盘点;机制修复不含存量清理 | [主记录](2026-09-24-admin-password-reset-issues.md#issue-20260924-zombie-credentials) | 待补 LESSON |
|
||||
| ISSUE-20260924-cursor-test-rule-drift | Cursor / test-reports / 固定模型 / 规则副本 | Cursor 测试规则与验证契约存在固定模型及范围冲突 | medium | verifying | Cursor | 2026-09-24;规则文本已缩为验证契约指针;客户端实际读取行为待实机 | [主记录](2026-09-24-subagent-workflow-research.md#4-issue-20260924-cursor-test-rule-drift) | [LESSON-20260924-cursor-hook-advisory-gates](../ops/lessons/2026-09-24-cursor-hook-advisory-gates.md) |
|
||||
| ISSUE-20260924-pi-executor-boundaries | PI executor / 路径规范化 / MCP / 子进程 / 幂等 | 未发布初版只读边界与执行可靠性缺陷 | high | resolved | Cursor/Codex | 2026-09-24;173 工程回归与真实 Cursor CLI/MCP/PI | [主记录](2026-09-24-pi-executor-boundaries.md) | [工具路径与输入隔离](../ops/lessons/2026-09-24-pi-tool-boundaries.md) |
|
||||
| ISSUE-20260924-cursor-cli-mcp-path | Cursor CLI / MCP / workspaceFolder / NDJSON | agentctl/jev MCP 加载失败(路径 + Content-Length 回包) | medium | verifying | Cursor | 2026-09-24;相对路径+NDJSON 已修;待 IDE 重载后 list-tools 实机 | [主记录](2026-09-24-pi-executor-boundaries.md#cursor-cli-mcp-path) | [LESSON-20260924-cursor-hook-advisory-gates](../ops/lessons/2026-09-24-cursor-hook-advisory-gates.md) |
|
||||
| ISSUE-20260924-cursor-hook-event-contract | Cursor / hooks / beforeMCPExecution / probe | hook 事件 stdin 字段名与 matcher 官方未文档化 | medium | verifying | Cursor | 2026-09-24;IDE postToolUse tool_name=`MCP:pi_subagent_roles` 已采样;beforeMCP 全量 stdin 仍缺 | [主记录](2026-09-24-cursor-hook-event-contract.md) | [LESSON-20260924-cursor-hook-advisory-gates](../ops/lessons/2026-09-24-cursor-hook-advisory-gates.md) |
|
||||
| ISSUE-20260924-non-author-400-duty | iam-authz / docgov / duty / 400 / 非编制 | 权限不足误报 400;run/edit 与编制职责绑死导致成员无法上传总结写草稿 | high | resolved | Cursor | 2026-09-24;真实 PI `TestNonAuthorMember_PiAgent_RunEditSubmitGates` PASS | [主记录](2026-09-24-non-author-member-access.md) | [LESSON-20260924-deny-only-submit](../ops/lessons/2026-09-24-deny-only-submit.md) |
|
||||
| ISSUE-20260926-docgov-snapshot-load | docgov / loadDocumentFromDBLocked / review_snapshot_id / 跨重启批准 | 文档装载 SELECT 漏 review_snapshot_id,重启/缓存未命中后最终批准必失败 | high | resolved | pi | 2026-09-26;隔离库 PG 回归 + dev 真实批准 200/state=approved(dev `121b33f8`) | [主记录](../test-reports/2026-09-26-rdev-p3-rerun-test-report.md#5-2) | 待补 LESSON |
|
||||
| ISSUE-20260926-docgov-uow-deadlock | docgov / persistApproveAndFAV / uow / FOR UPDATE / 57014 | docflow uow 行锁后 FAV 持久化自开第二连接更新同行,语句超时致死锁,所有最终批准失败 | critical | resolved | pi | 2026-09-26;生产形状 PG 回归(FOR UPDATE+FAV+Within)+ dev 真实批准转 200(dev `5d5cd5fd`) | [主记录](../test-reports/2026-09-26-rdev-p3-rerun-test-report.md#5-2) | 待补 LESSON |
|
||||
| ISSUE-20260926-docgov-memdocs-poison | docgov / memDocs / 状态机 / 持久化失败 / 缓存投毒 | 状态机先改内存后落库;持久化失败不复原,memDocs 缓存与 DB 永久分叉并掩盖真实错误(表现为「approved 状态」误报) | high | investigating | pi | 2026-09-26;dev 两次复现(快照/死锁两根因均被投毒掩盖);修复方向:失败时回滚内存快照或失效缓存条目 | [主记录](../test-reports/2026-09-26-rdev-p3-rerun-test-report.md#5-2) | 待补 LESSON |
|
||||
| ISSUE-20260926-ctx-idor | ctxmgr / GetUserContext / session_id / IDOR / handlers_context | GetUserContext 按 session_id 取消息无归属校验,登录用户可读他人会话正文(已证实) | critical | resolved | pi | 2026-09-26;handler 403 + SQL/内存双防线;内存 HTTP 与隔离 PG 回归 PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#1-find-sec-01-会话上下文-idorissue-20260926-ctx-idor) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
|
||||
| ISSUE-20260926-archcheck-untracked | archtest / table_owners / untracked / sql_write / 门禁盲区 | arch-check 对未登记表 SQL 写静默跳过,含 swboot_controlled_executions 等 ~50 表;门禁形同关闭 | critical | resolved | pi | 2026-09-26;未登记表 fail-closed + 补登 50 表 + 噪音豁免清单;arch-check block PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#2-find-arch-01-arch-check-未登记表静默跳过issue-20260926-archcheck-untracked) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
|
||||
| ISSUE-20260926-authz-failopen | authz / IsProjectMember / pool==nil / fail-open / NewInMemoryAuthorizer | Authorizer 无池时 IsProjectMember/IsProjectOwner 对任意登录用户返回 true,误配即全量放行 | high | resolved | pi | 2026-09-26;无池严格拒绝 + 显式内存授权接缝 + 组合根按 AllowInMemory 选择;隔离 PG authz 套件 PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#3-find-sec-02-authorizer-无池-fail-openissue-20260926-authz-failopen) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
|
||||
| ISSUE-20260926-swboot-shell-prefix | swboot / executor / sh -c / 命令注入 / 前缀白名单 / commandAllowed | 受控命令经 sh -c 执行且白名单前缀匹配(go 放行 go-evil);元字符可求值 | high | resolved | pi | 2026-09-26;argv 化 + basename 精确匹配;前缀伪装/不求值回归 PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#4-find-sec-03-swboot-sh--c--前缀白名单issue-20260926-swboot-shell-prefix) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
|
||||
| ISSUE-20260926-intentflow-validated-confirm | intentflow / DecisionConfirm / PlanProposed / validated_only / ExecuteClaimed | validated_only(shadow)计划可经 Confirm 进入 executing 并真实执行;执行器不读 ExecutionMode | high | resolved | pi | 2026-09-26;Confirm 拒 + 执行器硬拒双层 + 错误码/HTTP 映射;确认/派发双回归 PASS | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#5-find-flow-01-validated_only-可-confirm-后-dispatchissue-20260926-intentflow-validated-confirm) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
|
||||
| ISSUE-20260926-dual-flags-drift | intent / intentflow / FeatureFlags / PlanTier / MULTI_INTENT_ENABLED / 静默漂移 | 双套 flags 可配置出「intentflow 升档但 intent 关闭」的矛盾组合并静默降级 | high | resolved | pi | 2026-09-26;组合根经 intentflow.ValidateFlagConsistency 启动期 fail-fast + 单测;入口收敛残差另立 deferred | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#6-find-qual-01-双套-flags-静默漂移issue-20260926-dual-flags-drift含残差) | [LESSON-20260926-failclosed-bypass-contract](../ops/lessons/2026-09-26-failclosed-bypass-contract.md) |
|
||||
| ISSUE-20260926-governance-multi-entry | docgov / 多意图 / 多入口 / Coordinator / OwnerMux / GovernanceEngine | docgov 三入口 + Coordinator ~40 case 与 intentflow OwnerMux 平行,鉴权/确认/审计易漂移 | high | deferred | pi | 2026-09-26;flag 漂移面已修(dual-flags-drift);入口合并是多日级重构,需独立任务授权与回归矩阵 | [主记录](../remediation/2026-09-26-system-code-review-fixes.md#6-find-qual-01-双套-flags-静默漂移issue-20260926-dual-flags-drift含残差) | 沿用 failclosed-bypass-contract |
|
||||
| ISSUE-20260926-server-pool-wiring | server / swboot_handlers / Runtime.Pool / 组合根越界 / FIND-ARCH-02 | server 持 Pool 直装 swboot repo/executor 并直查表,成为第二组合根(本轮未授权修复) | critical | open | pi | 2026-09-26;代码审证据齐(审计 FIND-ARCH-02),待修复授权 | [主记录](../audit/2026-09-26-system-code-review.md) | 待修复后补 |
|
||||
| ISSUE-20260927-demo-fallback | web / App.tsx / sess-001 / projectId fallback / demo seeds 关闭 | demo seeds 关闭模式下前端硬编码 fallback(激活 sess-001、项目 1)对真实后端发假请求,新登录用户首屏 9 个 404/403(chat 窗口被迫回退本地缓存) | medium | resolved | pi | 2026-09-27;dev 真实浏览器修复前后对照(author+member 双账号:9 假请求→0) | [主记录](../ops/short-term/2026-09-27-frontend-demo-fallback.md) | [经验小结](../ops/short-term/2026-09-27-frontend-demo-fallback.md#经验小结)(独立 lesson 待后续任务补登) |
|
||||
| ISSUE-20260927-active-session-residue | web / storage.ts / loadActiveSessionId / localStorage 残留 / sess-001 / demo-seed-purge 写回窗口 | 旧前端把 demo fallback 值写回 localStorage active_session;一次性 purge 已执行不再清,读取侧无 legacy 校验,老浏览器 + 无可见会话账号首屏 4×chat 404(ISSUE-20260927-demo-fallback 修复残留路径) | medium | resolved | pi | 2026-09-27;dev 主入口 :3100 复验 admin+残留 sess-001:phantom=0/4xx5xx=0,key 被清除(dev `36c5fb54`) | [主记录](../ops/short-term/2026-09-27-frontend-demo-fallback-localstorage-residue.md) | [经验小结](../ops/short-term/2026-09-27-frontend-demo-fallback-localstorage-residue.md#经验小结补充-issue-20260927-经验) |
|
||||
@@ -16,7 +16,10 @@
|
||||
| GET /api/v1/tasks/runs/{id} | task_run | view | taskrun | 403 非 owner/非 owner 成员 |
|
||||
| POST /api/v1/tasks/runs/{id}/cancel | task_run | cancel | taskrun | 403 取消他人 |
|
||||
| POST /api/v1/chat/stream | chat | send | chat+stage | 403 无阶段权限 |
|
||||
| GET /api/v1/docgov/* | document | * | docgov+duty | 403 非职责人 |
|
||||
| GET /api/v1/docgov/* | document | * | docgov+duty | view:成员;run/edit:成员(deny_only_submit);submit/review/approve:对应职责,403 |
|
||||
| POST /api/v1/docgov/content | document | edit | docgov+member | 403 非项目成员或锁定态 |
|
||||
| POST /api/v1/docgov/submit-review | document | submit | docgov+author | 403 非编制职责人 |
|
||||
| POST /api/v1/tasks/run | task | run | bizdev+member | 403 非成员 / 非活动阶段;不再要求编制职责 |
|
||||
| GET /api/v1/admin/* | admin | * | authz RBAC | 403 非 admin/细粒度 perm |
|
||||
| GET /health, /api/v1/health | system | health | server | 公开 |
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Agent worktree 与 L1 操作规范
|
||||
|
||||
**修订**:`agent-governance-2026-09-21-r1`。来源:[AGENTS](../../AGENTS.md)、[规范登记](./2026-09-21-policy-registry.md)。工具为 `scripts/agentctl`(Python 标准库,Linux 本机),协议 v1;实际安装与验证见[实施任务](../archive/ops/2026-09-21-agent-governance-implementation.md)。
|
||||
**修订**:`agent-governance-2026-09-21-r1`。来源:[AGENTS](../../AGENTS.md)、[规范登记](./2026-09-21-policy-registry.md)。工具为 `scripts/agentctl`(Python 标准库,macOS/Linux 双平台),协议 v1;实际安装与验证见[实施任务](../archive/ops/2026-09-21-agent-governance-implementation.md)。
|
||||
|
||||
本规范约束合作 Agent 的统一操作入口和 Git 提交/引用门禁。任意同 UID shell、修改管理器或跳过 hooks 仍可绕过;不把 L1 宣称为 OS 沙箱。共享服务配置与产品数据库不属于任务素材。
|
||||
|
||||
@@ -121,13 +121,34 @@ validate 要求干净树、记录精确 HEAD 与命令摘要;必要的实际
|
||||
|
||||
任务状态、集成、部署、远端同步和 cleanup 分别记录,见[收口清单](./templates/session-close-checklist.md)。命令结束不等于任务完成;task close 会拒绝仍有运行或待恢复 operation 的任务。
|
||||
|
||||
### 8.1 只读盘点(先盘点,再人工处置)
|
||||
|
||||
```bash
|
||||
# 批量 worktree 清理就绪度;verdict=ready 才可考虑 remove。从不自动删除。
|
||||
./scripts/agentctl cleanup report
|
||||
|
||||
# FEATURE-MATRIX 状态漂移:硬告警仅 done→非 done(ISSUE-20260923 工具化);
|
||||
# open_capabilities 为人工判断候选。从不自动升 done / 写 MATRIX。
|
||||
./scripts/agentctl docs drift
|
||||
```
|
||||
|
||||
daemon 前台循环可按 `--audit-every N`(默认 30)周期跑上述盘点;**不在 daemon 内调用 `docs apply`**(主目录 cwd 必 `WORKTREE_MISMATCH`)。常驻 systemd/launchd 装载需独立授权,本规范默认不装载。
|
||||
|
||||
### 8.2 关闭与删除
|
||||
|
||||
```bash
|
||||
./scripts/agentctl task close --id task-id --status done
|
||||
./scripts/agent-worktree.sh remove feature/task-id --delete-branch
|
||||
```
|
||||
|
||||
清理由目录外的维护者执行,核对实际 Git 映射、dev 祖先、所有证据、tracked/untracked/ignored 文件、未完成 Git 操作、registry、生命周期锁和使用目录的进程。只用普通 remove/-d,拒绝时保留 cleanup_pending 和复查责任,不换成强制删除。
|
||||
清理由目录外的维护者执行,核对实际 Git 映射、dev 祖先、所有证据、tracked/untracked/ignored 文件、未完成 Git 操作、registry、生命周期锁和使用目录的进程。只用普通 remove/-d,拒绝时保留 cleanup_pending 和复查责任,不换成强制删除。盘点只读;删除仍人工;拒绝即保留 cleanup_pending。
|
||||
|
||||
**本机限制**:无法读取某些同 UID 进程 cwd 时,工具不能证明其未使用目录,故保留 cleanup_pending;只有明确识别的 OS 用户 systemd 管理进程有诊断性例外。测试中的 3 个删除正例仅替换 `/proc` 枚举以模拟可见主机,其余 Git/锁/文件条件为真实执行;可见占用、未知不可读、未合入、脏文件与活跃登记的拒绝另有真实/针对性测试。不要把这项限制转成跳过检查的通用开关。
|
||||
**本机限制**:无法读取某些同 UID 进程 cwd 时,工具不能证明其未使用目录,故保留 cleanup_pending;明确识别的 OS 用户 launchd(macOS)/systemd(Linux)管理进程有诊断性例外。进程 cwd 可见性走双路径:Darwin 用 `lsof`,Linux 用 `/proc`;测试中的删除正例可替换对应枚举以模拟可见主机,其余 Git/锁/文件条件为真实执行;可见占用、未知不可读、未合入、脏文件与活跃登记的拒绝另有真实/针对性测试。不要把这项限制转成跳过检查的通用开关。
|
||||
|
||||
保护任务、旧 detached 工作区和非本次产物不自动清理。用户未要求 push 时仅本地提交/合入;用户已要求时再按授权同步并核对远端引用。
|
||||
|
||||
### 8.3 CodeGraph(治理加速器)
|
||||
|
||||
- `agentctl init` 与 `agent-worktree.sh create` 会 best-effort 初始化/同步 `.codegraph/`(CLI 缺失则跳过,不阻断)。
|
||||
- `hooks install` 安装 `post-merge` / `post-checkout` → `hooks codegraph-sync`(fail-open,永不阻断 integrate)。
|
||||
- 会话启动执行 `codegraph sync -q`。索引是 tree-sitter **近似**:有假阴性;**grep 是完整性唯一权威**;重命名与穷举调用方必须 grep 确认。
|
||||
|
||||
@@ -27,3 +27,41 @@ CURRENT 是带时间的活跃协调快照;Git/机器状态用于核验实际
|
||||
## Herdr v1.2 局部修订
|
||||
|
||||
用户已授权采纳经研究修正的资源分工与自动审批。Herdr roster 的角色/额度/客户端参数由 `herdr-v1.2` 取代旧路由,仅在明确使用 Herdr 时激活,不扩展通用会话工作流。具体来源、验证与生效集成见[本轮任务](../archive/ops/2026-09-21-herdr-orchestration-v12.md)。已通过 dev 合并提交 `8c5e3477585fe27a485343dac97a670d95cf8905` 生效;profile/dry-run、入口保护和 Kimi 原子计数有隔离验收,真实 Herdr pane 启动未在本轮执行,不将其记为已实测。
|
||||
|
||||
## 系统问题分析局部修订
|
||||
|
||||
修订 ID:`systemic-issue-analysis-2026-09-23-r1`;owner:`Codex`;state:`active`(已通过 `958dd44fee8bbea8d19129457fc0ad749fdebdbe` 合入 dev);工具能力:`manual`。用户明确要求将“由个案追查同类根因、潜在问题,研究并提出方案”加入规范,授权与验证见 [任务记录](./short-term/2026-09-23-systemic-issue-analysis.md)。
|
||||
|
||||
核心行为唯一来源为 [AGENTS 分析要求](../../AGENTS.md#bug-与系统问题的分析要求),验证范围由 [验证契约](./2026-09-21-validation-contract.md#问题修复的回归范围) 定义,[分析模板](./templates/audit-note.md) 承载证据。客户端继续引用统一入口。生效提交为 `958dd44fee8bbea8d19129457fc0ad749fdebdbe`,候选验证与受控集成收据见任务记录;不新增业务实施或环境操作授权。
|
||||
|
||||
## 问题记录与经验复用局部修订
|
||||
|
||||
修订 ID:`issue-learning-2026-09-23-r1`;owner:Codex;state:`active`(已通过 `7bbd7a407f857515005c0324d90339017ea5f3e8` 合入 dev);执行能力:`manual`。用户要求同时管理出现的问题、修复记录和思路,并及时总结为开发注意事项,授权与验证见 [任务](short-term/2026-09-23-issue-learning.md)。
|
||||
|
||||
[闭环规范](2026-09-23-issue-learning-workflow.md) 为本流程唯一来源;AGENTS 增加按任务触发的读取/更新入口,模板承载证据,问题台账和经验索引提供检索。生效提交为包含本修订的首个受控 dev 集成提交,以任务收据与 Git 父链核实;未合入不能声称全仓生效。此修订不新增产品功能、自动门禁或运行权限。
|
||||
|
||||
## CodeGraph 与只读盘点局部修订
|
||||
|
||||
修订 ID:`codegraph-governance-2026-09-24-r1`;owner:`Cursor`;state:`active`(生效 tip `19eb56e3744d3c7d4b69b065c87e27689e8caa53` / fixup `0c676afe1faf831020c7c3201509d7cec0328d53`);工具能力:盘点命令与 hooks sync 为 `enforced`(脚本已落地);常驻 daemon 装载仍为 `manual`(本机默认不装载)。用户授权:将 CodeGraph 纳入治理启动/建场/sync,并对 worktree 清理与 FEATURE-MATRIX 做只读盘点提醒(不自动删除、不自动升 done)。
|
||||
|
||||
唯一来源增补:[AGENTS §1/§4](../../AGENTS.md)、[worktree 操作规范 §8](./2026-09-21-agent-worktree-workflow.md)、[收口清单](./templates/session-close-checklist.md)。命令入口:`agentctl cleanup report`、`agentctl docs drift`、`agentctl hooks codegraph-sync`、建场 `agent-worktree.sh create` 的 best-effort `codegraph init`。不改产品 SWBOOT-10 stub,不装载 systemd coordinator(需另授)。
|
||||
|
||||
## Subagent 工作流拟议修订
|
||||
|
||||
修订 ID:`subagent-workflow-2026-09-24-r2`;owner:Codex;state:`proposed`;能力:`manual`;effective_commit:无。
|
||||
用户要求研究 Cursor Auto 下的 subagent 分工、阶段流程及报告,授权与本次验收见[任务](short-term/2026-09-24-subagent-workflow-standard.md)。[规范草案](2026-09-24-subagent-workflow-standard.md)为拟议行为的唯一来源,[研究报告](../audit/2026-09-24-subagent-workflow-research.md)给出事实和待修冲突,[模板](templates/subagent-stage-record.md)承载交接。
|
||||
用户后续明确采用 Cursor Auto 实施 + gmktec 本机 PI 子任务,并批准默认模型分工及可调整文档。[模型配置](2026-09-24-subagent-model-config.md)为模型路由唯一来源,decision_state=approved;流程整体仍 proposed;已批准的模型配置与执行器已合入本地 dev。原 Cursor 原生角色/inherit 方案被替代。执行器已在任务分支实现并验证 Cursor CLI→MCP→PI,代码 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119;[运行说明](2026-09-24-pi-subagent-executor.md)与[验证报告](../test-reports/2026-09-24-pi-executor-test-report.md)限定已验证的机器边界。dev 集成/完整流程审批仍独立记录;不以派发器可用宣称全阶段自动门禁。
|
||||
|
||||
## Cursor 治理层局部修订
|
||||
|
||||
修订 ID:`cursor-governance-2026-09-24-r1`;owner:`Cursor`;state:合入 local_dev 后 `active`(effective_commit 以集成收据为准);工具能力分层:
|
||||
- 规则/skill 文本:`manual`(Agent 读取执行)
|
||||
- hook 脚本 stdin→stdout 行为:`enforced`(`scripts/tests/test_cursor_hooks.py`)
|
||||
- hook ↔ Cursor IDE 接线:`advisory`/`manual`(事件字段待 probe 采样;见 ISSUE-20260924-cursor-hook-event-contract)
|
||||
|
||||
用户授权:在 PI 执行器合入后补齐 skills/rules/hooks;范围与验收见[任务](short-term/2026-09-24-cursor-governance-hooks.md)。客户端入口:`.cursor/rules/cursor-hooks.mdc`、`pi-subagents.mdc`、`test-reports-standard.mdc`(缩为验证契约指针);skills `pi-subagent-dispatch` / `subagent-stage-record`;hooks 见 `.cursor/hooks.json`。不改变产品 Runner、不扩大执行器硬门禁语义。
|
||||
|
||||
## 治理目录库与需求重叠检测拟议修订
|
||||
|
||||
修订 ID:`governance-catalog-2026-09-24-r1`;owner:`Cursor`;state:`proposed`;能力:schema/门禁落地后为 `enforced`,向量层 `fail-open`;effective_commit:无(随受控合入记录)。
|
||||
用户授权实施跨对话需求重叠检测与治理目录(扩展既有 `.locks/state.sqlite`,不碰业务 PG)。唯一来源:[方案](./2026-09-24-governance-catalog-plan.md);任务:[short-term](./short-term/2026-09-24-governance-catalog.md)。策略键 `catalog_gate`/`catalog_vector` 为可选,不得破坏 `shared_docs` 等集合相等校验。
|
||||
|
||||
@@ -15,6 +15,12 @@
|
||||
|
||||
多类变更取并集。按 [模块开发标准](../system-design/2026-09-20-module-development-standards.md) 追加边界与 registry parity 等范围门禁。开发阶段可用 stub;交付验收不能冒充真实执行。纯文档无需产品 PI 或全量 Go,也不为形式重建服务。
|
||||
|
||||
## 问题修复的回归范围
|
||||
|
||||
Bug/系统问题修复先按 [AGENTS 分析要求](../../AGENTS.md#bug-与系统问题的分析要求) 确定问题类别和影响范围,再从上表选择验证层级。验收须包含:原始复现案例;通过同一机制的其他输入、措辞或入口;相关边界/异常路径;应保持不变的正常行为。场景按实际因果链选择,不机械穷举;不适用或未覆盖的项记录理由与风险。
|
||||
|
||||
验证机制和预期行为,不以硬编码原句、固定回复文本或单个样例通过代替回归。能在修复前复现失败的场景记录修复前后对照;不能复现时说明证据限制。报告逐项区分通过、失败、未运行与待验证;只提供分析/方案时列出验收设计,不声称已经运行或修复。
|
||||
|
||||
## 产品 PI 基线与精确追加
|
||||
|
||||
优先入口:`./scripts/run-nightly-real-pi.sh`。调用前核验并从获授权配置提供(不在命令/报告贴凭证值):
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
---
|
||||
title: "agentctl Cursor 能力层(skills / MCP / rules / hooks)"
|
||||
status: active
|
||||
created: 2026-09-23
|
||||
updated: 2026-09-23
|
||||
owner: Cursor
|
||||
task_id: agentctl-cursor-integration-2026-09-23
|
||||
---
|
||||
|
||||
# agentctl Cursor 能力层
|
||||
|
||||
把已上线的 agentctl 管理面包装为 Cursor 原生能力,使 agent 默认走租约 / docs 收据 / 候选合入。
|
||||
|
||||
## 能力清单
|
||||
|
||||
| 层 | 路径 | 作用 |
|
||||
|---|---|---|
|
||||
| MCP | [`.cursor/mcp.json`](../../.cursor/mcp.json) → [`scripts/mcp/agentctl-mcp.mjs`](../../scripts/mcp/agentctl-mcp.mjs) | `status` / `task_*` / `lease_run` / `docs_*` / `validate` / `queue_enqueue` / `quarantine_status` |
|
||||
| Skills | [`.cursor/skills/agentctl-*`](../../.cursor/skills/) | 会话启动、建场、租约写、集成收口 |
|
||||
| Rule | [`.cursor/rules/agentctl-mandatory.mdc`](../../.cursor/rules/agentctl-mandatory.mdc) | alwaysApply:强制走 agentctl |
|
||||
| Hooks | [`.cursor/hooks.json`](../../.cursor/hooks.json) + `guard-git.sh` | `git push` / 破坏性 git → `permission: ask` |
|
||||
|
||||
权威规则仍是 [AGENTS.md](../../AGENTS.md) 与 [操作规范](./2026-09-21-agent-worktree-workflow.md);本目录不复制全文。
|
||||
|
||||
## 启用
|
||||
|
||||
1. 合入 local `dev` 后,在 Cursor 中 **Reload Window** 或重载 MCP。
|
||||
2. 确认 MCP 服务器 `agentctl` 出现在工具列表;hooks 出现在 Cursor Hooks 设置页。
|
||||
3. 会话开始跟 skill `agentctl-session-start`(核对 `daemon status`)。
|
||||
|
||||
## 与管理面关系
|
||||
|
||||
- launchd `com.agentctl.coordinator` 持续 `queue schedule`;本能力层只封装 CLI,不替代 daemon。
|
||||
- git hooks(pre-commit / pre-merge / reference-transaction)仍由 `agentctl hooks` 管理,与 Cursor `beforeShellExecution` 互补:前者执行租约/候选门禁,后者拦未授权 push/强推。
|
||||
|
||||
## 非目标
|
||||
|
||||
不 push;不晋升 test/main;不改 gap-matrix;不卸载 daemon。
|
||||
@@ -0,0 +1,61 @@
|
||||
# 问题记录与开发经验闭环
|
||||
|
||||
修订:`issue-learning-2026-09-23-r1`;owner:Codex;生效条件见 [规范登记](2026-09-21-policy-registry.md)。执行能力为 `manual`:依靠 Agent 读取、任务记录与审查;本轮没有增加自动检索、CI 阻断或模型训练。
|
||||
|
||||
## 入口与职责
|
||||
|
||||
| 入口 | 回答的问题 | 权威边界 |
|
||||
|---|---|---|
|
||||
| [问题台账](../audit/ISSUES.md) | 出现过什么问题,目前处理到哪一步? | 索引和状态投影;事实、修复经过以链接的唯一问题主记录为准 |
|
||||
| 问题主记录 | 为什么发生、考虑过哪些方案、改了什么、如何验证? | 放 audit,或沿用已有任务/审计中的明确章节;使用 [问题模板](templates/issue-record.md) |
|
||||
| [开发经验](lessons/INDEX.md) | 遇到类似工作应先检查什么? | 按机制提炼的注意事项;使用 [经验模板](templates/development-lesson.md),不替代现行规范 |
|
||||
| CURRENT / FEATURE-MATRIX / gap-matrix | 当前协调 / 能力 / 发布门禁 | 维持原职责;只有对应状态改变才更新 |
|
||||
|
||||
修复方案、任务、提交、验收报告通过链接串联,已有材料直接复用。一个 task 可处理多个 issue,一个 issue 可跨分析/实施任务;研究任务 done 不等于问题 resolved。一个 lesson 可覆盖多个同根因 issue。短问题可在任务主文档内记录,无需机械创建一套文件。
|
||||
|
||||
## 何时记录、检索和总结
|
||||
|
||||
1. **设计、编码、排障或运维前**:按模块、路径、错误码、症状和共用机制检索问题台账及经验索引。先查索引、再读命中条目的来源;核对当前源码/规范是否仍适用。在任务记录填写检索词、命中 ID、采纳的检查;无命中明确记录。简单信息答复不要求建任务或检索整库。
|
||||
2. **首次发现问题时**:在当前任务 worktree 建立或补充问题主记录和台账行,记录预期/实际、影响、环境/版本、owner、下一步及证据缺口;尚未定位也可以登记。ID 使用 `ISSUE-YYYYMMDD-<slug>`,日期为登记日;发生日期另列,跨 worktree 以语义 slug 避免抢序号。
|
||||
3. **定位、改方案、完成修复或发现验收失败时**:在同一主记录追加时间线和尝试结果;保留被否定假设、失败方案及不适用条件,区分观察、推测和已证实根因。按 [问题分析要求](../../AGENTS.md#bug-与系统问题的分析要求) 检查共用机制和同类入口。
|
||||
4. **根因与修复得到验证后、任务收口前**:提炼经验或更新已有同机制经验,并链接回问题。若尚无验证证据,只能建 `candidate`;若没有新增可复用结论,记“不新增经验”及理由,仍保留问题记录。分析-only、未修复或验收失败的问题继续留在台账。
|
||||
5. **经验落到开发动作**:写清触发条件、机制、应做检查、错误做法及原因、验证方法、适用边界。优先链接现有测试/约束;需要新增回归、lint、架构门禁或规范时,在当前授权内实施,超出授权则记录 owner/后续任务。仅提出自动化建议不能标为已落实。
|
||||
6. **复发或规则变化时**:同一故障未解决的复现追加原 issue;已关闭问题再次出现,重开原 issue 为 `investigating`,递增 `recurrence_count` 并保留原关闭证据。不同根因建立新 issue 并互相链接。复盘为何已有经验/测试未生效:未检索、范围不适用、遗漏入口、检查未执行或实现回退,并更新防护。模块/接口/规范变化时复核命中经验;确认过时标 `superseded` 并链接替代条目,无替代则 `retired`,保留历史。
|
||||
|
||||
检索示例(在任务工作区执行,替换为本任务关键词):
|
||||
|
||||
```bash
|
||||
rg -n -i 'docgov|nullable|23503|职责' .doc/audit/ISSUES.md .doc/ops/lessons
|
||||
```
|
||||
|
||||
owner 在上述里程碑及时更新,最迟在会话交接前保存事实和未完成项;不依赖定时服务。经验不会自动改变模型参数,作用是让后续 Agent 能检索、有证据地复用,并逐步把重复风险转换为可执行检查。
|
||||
|
||||
## 问题状态与关闭条件
|
||||
|
||||
问题的 `issue_state` 与任务 `status` 分开;台账保留当前投影,主记录保留变迁历史。
|
||||
|
||||
| issue_state | 含义 / 转移要求 |
|
||||
|---|---|
|
||||
| open | 已登记,等待定位 |
|
||||
| investigating | 正在复现、验证假设和范围 |
|
||||
| fixing | 修复方案明确且已获实施授权 |
|
||||
| verifying | 修复待验收,或必要证据尚缺 |
|
||||
| resolved | 约定范围的修复、必要环境验收均有证据,经验已总结或有不新增理由 |
|
||||
| deferred | 暂缓处理;保留风险、责任人、复查触发和授权/决策依据,不冒充修复 |
|
||||
| duplicate | 指向唯一主 issue,保留原报告和去重理由 |
|
||||
|
||||
定位失败可保留 investigating;临时止血不代表 resolved,必须标清剩余根治项。验证失败回到 investigating/fixing,不能覆盖失败记录。关闭至少能追溯:根因、同类范围、修复提交或获授权的处理动作、原例/变体/正常行为验收及缺项、实际部署状态、lesson 或不新增理由。业务改动待部署时不能把目标环境问题关闭;无需部署写 not_required。
|
||||
|
||||
**历史补录**:发生日、修复日和补录日分开。只按旧报告已证明的范围记录 `resolved`,同时标 `evidence_basis=historical` 和当前运行未复测;缺乏关闭证据用 `verifying` 并说明原因,不从旧任务 done 推导修复完成。历史条目不能用于宣布当前系统就绪。本轮仅补录两个有来源案例,不代表穷尽全部历史问题。
|
||||
|
||||
## 经验质量与维护
|
||||
|
||||
`lesson_state`:`candidate | validated | superseded | retired`。validated 表示注意事项有可核对的因果证据且已复核适用边界,不表示所有模块或当前线上均测试通过。需记录 reviewer、last_reviewed、reviewed_revision、来源 issue、证据日期、关键词、关联测试、适用/不适用范围及仍缺的防护。
|
||||
|
||||
同机制优先更新已有 lesson,保留修订记录;新机制才新增 `LESSON-YYYYMMDD-<slug>`。将通用经验升级成强制规范时,只在对应规范的唯一来源修改并登记生效条件,经验条目保留理由与链接。经验与现行规范冲突时先按有效规范执行,登记冲突与复核项;历史经验不能授予数据修复、部署或扩大范围的权限。
|
||||
|
||||
## 并发、验收与敏感信息
|
||||
|
||||
所有写入沿用 [worktree 操作规范](2026-09-21-agent-worktree-workflow.md)。问题/经验索引使用各自 `path:` 短租约;当前 `agentctl docs apply` 仅覆盖 CURRENT/FEATURE-MATRIX,不宣称新索引有行级 CAS。写入前读最新内容、只改自己的条目;从旧 dev 分出的工作区在集成前合并最新 dev 并处理索引冲突,保留他人条目。索引和主记录在同一逻辑提交同步,避免状态分叉。
|
||||
|
||||
文档验收包括链接/锚点、ID 唯一、主记录与索引状态一致、来源及日期、入口/模板可达和情景检查。运行回归按 [验证契约](2026-09-21-validation-contract.md);未运行、缺项与历史证据单独标明。只保留足够判断的脱敏证据,业务正文、凭证和个人数据不复制进经验库。
|
||||
@@ -0,0 +1,46 @@
|
||||
# 治理目录库与跨对话需求重叠检测(方案)
|
||||
|
||||
**修订 ID**:`governance-catalog-2026-09-24-r1`
|
||||
**state**:`proposed` → 实施后随合入升 `active`
|
||||
**owner**:Cursor
|
||||
**工具能力**:schema/CRUD/门禁 `enforced`(落地后);向量层 `fail-open`
|
||||
**任务**:[short-term](./short-term/2026-09-24-governance-catalog.md)
|
||||
|
||||
## 问题
|
||||
|
||||
跨对话新设计与既有功能/需求重叠时,现有 agentctl 仅做路径级 `overlaps()` 互斥,无需求语义比对。CURRENT/ISSUES/test-reports 为 Markdown 台账,机器无法强制开工前探测。
|
||||
|
||||
## 方案摘要
|
||||
|
||||
在既有 `.locks/state.sqlite`(与业务 PG 物理隔离)上 additive 扩展 Catalog 表:
|
||||
|
||||
| 表 | 用途 |
|
||||
|---|---|
|
||||
| `catalog_requirements` | R-ID 需求条目 |
|
||||
| `catalog_features` | 对齐 FEATURE-MATRIX record_id |
|
||||
| `catalog_req_text` | FTS5 CJK 逐字索引(禁用 trigram) |
|
||||
| `catalog_overlaps` / `catalog_decisions` | 检测结果与裁决留痕 |
|
||||
| `catalog_issues` / `catalog_tests` / `catalog_releases` | 缺陷/测试/发布投影 |
|
||||
| `catalog_embeddings` | 可降级向量增强 |
|
||||
|
||||
### 分级门禁
|
||||
|
||||
1. **L1 结构化**:`same_mutex` / `same_feature` / `same_scope` / `same_req_id` → hard deny
|
||||
2. **L2 语义**:FTS5 bm25 软门,须 `catalog overlap ack` 显式裁决后才可编码
|
||||
3. **L3 向量**:读 `EMBEDDING_*`;401/超时/缺钥 → `vector_layer=degraded`,不阻断
|
||||
|
||||
### 策略
|
||||
|
||||
`catalog_gate` / `catalog_vector` 为**可选键**(不得加入 `shared_docs` 等集合相等校验字段)。
|
||||
|
||||
### 权威关系
|
||||
|
||||
`.doc` Markdown 仍为事实来源;Catalog 为可检索投影 + 门禁依据;冲突时 `catalog drift` 告警,不自动改文档。
|
||||
|
||||
## 边界
|
||||
|
||||
不新建第二库/容器;不读写业务 PostgreSQL;不改 `overlaps()` 既有语义;不做跨机权威。
|
||||
|
||||
## CLI / MCP
|
||||
|
||||
`agentctl catalog {add,list,show,search,overlap,ack,status,drift}`;MCP:`catalog_requirement_add` / `catalog_overlap_probe` / `catalog_overlap_ack` / `catalog_search` / `catalog_status`。
|
||||
@@ -0,0 +1,47 @@
|
||||
# 本机 PI Subagent 执行器接入方案与实施记录
|
||||
|
||||
task_id:subagent-workflow-standard-2026-09-24;operation_task_id:subagent-workflow-standard-2026-09-24-executor。
|
||||
用户授权:“接入自动调用 pi 的执行器”;既有约束:Cursor Auto 实施,PI 模型限[配置](2026-09-24-subagent-model-config.md),M3 默认停用。本次是同任务的实现续作。
|
||||
|
||||
## 目标与边界
|
||||
|
||||
Cursor 能通过项目 MCP 自动按角色调用 gmktec 本机 PI,读取配置,提供冻结输入,获得持久报告和可核验状态。CLI 同步提供可复现入口。
|
||||
不修改产品服务/Runner、不操作真实业务数据、不安装 daemon、不 push。代码只在原登记 worktree 修改,当前 main 有其他任务的未跟踪 promotion receipt,保留不动。
|
||||
本次复核 local dev=6858e21d477571696a8458032e2c884449e773fd;原任务 HEAD=52462b45e985f596b2a503fc70ac12c3bd5fe571;新增 dev 差异为 internal/squad,与本次脚本无交叉。没有重新建场或切换主目录分支。
|
||||
|
||||
## 分工与执行方式
|
||||
|
||||
- Cursor Auto:编写执行器、MCP 接口、权限限制与测试。host Codex:需求/契约、文档、证据核验、审查与受控提交。
|
||||
- Cursor CLI 在已登记原任务 worktree、agentctl with 监督和精确路径租约内执行;不授予提交/合并/推送/环境操作权限。模型请求 Auto;实际底层模型不可见时记录 unknown。
|
||||
- 本次使用 ce-work 的执行/验证思路、CodeGraph 定位、test-driven-development 和 writing-for-agents。仓库 AGENTS 的原任务 worktree/agentctl 规则优先于技能中 detached 临时工作区机制;使用仓库 supervisor 派发 Cursor,代码路径单写者,外层核对差异。该隔离不是 OS 沙箱。
|
||||
- 范围:scripts/pi_subagents.py、scripts/pi-subagent-readonly.ts、scripts/mcp/pi-subagents-mcp.mjs、scripts/tests/test_pi_subagents.py、scripts/mcp/README.md、.cursor/mcp.json、.cursor/rules/pi-subagents.mdc,以及本任务相关 .doc 文档。
|
||||
- 认领能力仅 docs:publish;不注册 env:* 或 git:dev。后续集成另按受控候选流程处理。
|
||||
|
||||
## 设计契约
|
||||
|
||||
1. 配置文档是唯一模型来源,每次派发解析严格表格,记录 revision/hash 和实际 provider/model。禁用、未知、循环、M3 关键职责路由失败关闭;没有静默备用。
|
||||
2. 新鲜 PI 会话;冻结 source SHA 与显式 tracked 输入文件(拒绝秘密/业务 data/路径穿越/符号链接),上限限制。模型只得到选定输入与允许的只读工具,无任意 shell、源码写入或递归派发。
|
||||
3. 测试角色仅运行主 Agent 显式提供、带来源的 argv 计划;独立源码副本、净化环境、超时和输出限制,模型不生成可执行命令。共享业务环境本版不接入,返回明确限制。
|
||||
4. MCP 提供角色预览、运行、结果查询;跨 worktree 调用核对同仓与 task 注册;运行由权威 agentctl with 包裹,并由执行器校验继承租约。
|
||||
5. 每个 request_id 绑定输入摘要;同请求重放只查询,变更载荷拒绝,running/unknown 不重派。每请求独立短范围 report 路径锁,跨调用者统一并发上限。
|
||||
6. 运行前保存 running;完成保存 receipt.json/report.md,含命令、版本、输入摘要、配置摘要、状态/结论、报告来源。结果未知/失败不冒充通过,进程退出0不替代模型最终事件和必需测试结果。
|
||||
7. timeout/cancel 处理进程组并回收;未知副作用保留现场。凭证仅由 PI 客户端读取,绝不进入模型输入/报告;测试子进程不继承模型密钥或租约身份。
|
||||
8. MCP 用标准 stdio JSON-RPC,查询不被运行调用阻塞。项目规则告诉 Cursor 何时选择哪种 role_id,具体模型仍从配置读取。
|
||||
9. 实施与修复始终交给 Cursor;PI 负责分析/审查/验证。模型结论和 acceptance_owner 的最终验收分开。
|
||||
|
||||
## 验证计划
|
||||
|
||||
- 隔离真实 Git/agentctl:注册/租约负例、路径范围、报告落盘、请求幂等、并发与异常退出。
|
||||
- 本地假 PI 仅作为协议传输夹具:模型参数、权限开关、JSON 事件、错误/空响应/超时/子进程清理;不得当作真实模型能力验收。
|
||||
- MCP 实进程:initialize、tools/list、roles、run、result;错误必须 isError。
|
||||
- 实际本机 PI:至少一条真实分析请求与独立代码审查;模型/权限/配置/源码身份可追溯。不得把 CLI/MCP 接口实测写成 Cursor IDE 页面已实测。
|
||||
- 主机核验聚焦测试与工程脚本套件,按失败证据补回归;无需运行无关产品全量 Go、重建服务或产品 PI。
|
||||
- 收口保留运行结果和剩余条件,分别记录 local commit / integration / deployment / remote_sync / cleanup。
|
||||
|
||||
## 当前进度
|
||||
|
||||
2026-09-24:Cursor Auto 已在 agentctl supervisor 内启动;本轮尚未宣称实现完成。机器租约身份和终端输出由 host 核验,待实施结果后补测试与审查。
|
||||
|
||||
## 已验证结果
|
||||
|
||||
执行器代码已提交为 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119。完整工程回归 173 项、提交后专项 34 项、真实 Cursor CLI→MCP→PI 自动路由与最终 ls/read 均通过,详见[报告](../test-reports/2026-09-24-pi-executor-test-report.md)。文档配置已改为程序读取;完整审批状态机仍人工/Agent 遵约。已受控合入本地 dev,集成提交 5a8540804ee2d142a0894c1482a2a16e8f843915,未推送;Cursor IDE 页面仍未实测。
|
||||
@@ -0,0 +1,80 @@
|
||||
# 本机 PI Subagent 执行器使用说明
|
||||
|
||||
范围:Cursor Auto 主协调/代码实施,gmktec 本机 PI 子任务。模型分工唯一来源为[模型配置](2026-09-24-subagent-model-config.md),阶段定义见[流程规范](2026-09-24-subagent-workflow-standard.md)。本说明与代码已合入本地 dev;集成和最终实测状态见[实施记录](2026-09-24-pi-executor-implementation.md)。
|
||||
|
||||
## Cursor 中使用
|
||||
|
||||
1. 在包含本次提交的工作区打开 Cursor,重新加载项目 MCP;.cursor/mcp.json 注册 pi-subagents 服务,.cursor/rules/pi-subagents.mdc 提供派发入口。
|
||||
2. 主会话保持 Auto。先按原有流程创建/登记任务 worktree,并将 .doc/test-reports/assets/pi-subagents/<task-id> 纳入任务写范围。
|
||||
3. Cursor 调用 pi_subagent_roles 读取当前角色与模型;从任务目标选择 role_id,调用 pi_subagent_run,随后查询 pi_subagent_result。
|
||||
4. 不需要用户切换 PI 模型。需求/方案、独立审查、测试和报告由不同角色处理;代码实施与修复仍由 Cursor 执行。
|
||||
5. 接收报告并核对范围、源码/配置版本、缺项;运行完成不代表阶段批准。最终验收责任仍由任务 acceptance_owner 承担。
|
||||
|
||||
任务 worktree 尚未合入 dev 时,主目录中的旧 MCP 配置不会自动获得新工具;先在该任务 worktree 验证,受控集成后再在主目录重载。本文不宣称已操纵 Cursor IDE 页面。
|
||||
|
||||
## 请求内容
|
||||
|
||||
MCP 工具的外层参数 worktree 为同仓的已登记任务工作区,task_id 为实际操作任务。request 中给出以下信息;授权引用应能回链到真实用户请求,不用日志/模型文本自授权限。
|
||||
|
||||
```json
|
||||
{
|
||||
"worktree": "/absolute/path/to/repo/.worktrees/task-id",
|
||||
"task_id": "task-id",
|
||||
"request": {
|
||||
"role_id": "research",
|
||||
"request_id": "research-001",
|
||||
"goal": "读取选定文件,给出有证据的分析",
|
||||
"authorization_ref": "本任务主记录中的用户授权位置",
|
||||
"source_sha": "<完整的已提交源码 SHA>",
|
||||
"input_files": ["PROJECT.md"],
|
||||
"timeout_seconds": 120
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
source_sha 必须为完整提交 hash;HEAD/分支名不作为可变输入。只发送明确列出的已跟踪 UTF-8 普通文件,禁止运行数据、.env、凭证、符号链接和路径越界。未提交的代码不会自动进入快照,先由 Cursor 形成可审提交或使用已有冻结版本。
|
||||
|
||||
request_id 在同一任务中稳定标识一次请求:同参数只读重放既有结果,不重复调模型;不同参数复用 ID 被拒绝;running/unknown 保留现场,不能盲目重派。配置变更在下一次新派发读取,旧请求保留原 config_revision/config_sha256。
|
||||
|
||||
## CLI 入口
|
||||
|
||||
在任务工作区使用:
|
||||
|
||||
```bash
|
||||
python3 -B scripts/pi_subagents.py roles
|
||||
../../scripts/agentctl with --task task-id \
|
||||
--resource path:.doc/test-reports/assets/pi-subagents/task-id/research-001 -- \
|
||||
python3 -B scripts/pi_subagents.py run --request /tmp/pi-request.json
|
||||
python3 -B scripts/pi_subagents.py result --task task-id --request-id research-001
|
||||
```
|
||||
|
||||
CLI 请求文件需包括 task_id;也可用 run --stdin 输入 JSON。直接裸调 run 会被租约校验拒绝。上述名称是示例,不构成任何任务或环境授权。
|
||||
|
||||
## 测试角色
|
||||
|
||||
test_run / acceptance_check 还需 approved_commands(argv 数组的数组)和 plan_digest(外部已批准计划 SHA-256);执行器另记录 approved_commands_sha256,不能以任意字符串冒充命令与计划的同一摘要。
|
||||
|
||||
命令在独立测试快照中运行,使用净化环境和私有 HOME/cache/tmp,标准输入关闭。PI 模型根据收到的命令摘要、退出码和日志引用分析,不生成或修改被执行命令;完整日志由主 Agent 核验并在需要时补充上下文。模型分析快照保持原始源码内容,与测试可写副本分离。必要的 stdout/stderr 保存到本请求报告目录以便核对,不仅保留一段摘要。
|
||||
|
||||
依赖未安装、用例缺失或命令失败须如实记录。本版不自动安装依赖,不直接连接共享 dev/test/main 或操作真实业务数据;相关检查继续由主 Agent 通过现有环境授权/租约流程执行。命令退出 0 只证明命令层执行成功;必需用例是否执行、SKIP、持久性/UI 和业务验收仍按验证契约核对。
|
||||
|
||||
## 证据与状态
|
||||
|
||||
输出位置:.doc/test-reports/assets/pi-subagents/<task-id>/<request-id>/。
|
||||
|
||||
- receipt.json:请求摘要、配置摘要、源码/输入文件摘要、配置与观察到的模型、运行状态、命令结果、工具调用摘要。
|
||||
- report.md:可读报告;模型分析是审查输入,主 Agent 核对后再推进阶段。
|
||||
- 命令日志:按收据记录的位置查询;报告目录受对应 path 租约保护。
|
||||
- 模型私有 thinking 不作为归档材料。错误输出与日志按敏感信息规则处理;不保存凭证。
|
||||
|
||||
run_status 与 verdict 分开:模型正常结束可以是 succeeded,但非测试报告仍为 review_state=pending / verdict=not_applicable。测试报告的 commands_passed/pass 只针对提交的命令,不能直接赋值到任务的 review_state 或 acceptance。失败、取消、结果未知不能换成 PASS。
|
||||
|
||||
超时、取消和输出超限处理整个受控进程组。只读结果查询可推断 orphan 为 unknown,但不能通过查询无租约改写收据。错误前置检查未形成业务收据时,MCP 返回可核对的执行拒绝,不能让主 Agent 一直等待不存在的结果。
|
||||
|
||||
## 调整与边界
|
||||
|
||||
角色默认模型、enabled、升级角色和并发上限在模型配置文档维护。禁用角色前同步处理指向它的升级关系。程序仅接受当前明确批准的五个 provider/model 组合;扩大模型池还需用户授权并更新硬边界校验,不是任意改一行即放宽权限。
|
||||
|
||||
本工具提供配置解析、模型启动、有限工具/输入范围、租约、进程监督和证据保存;没有把全部 S0–S9 的审批实现成不可跳过的状态机。Cursor 通过规则决定何时调用;模型失败不会触发隐式换 provider 或降级到 M3。
|
||||
|
||||
进程组和工具权限限制不是 OS 沙箱。批准的测试代码与本机工程工具属于可信执行面;外部不可信项目/代码不能因使用本工具就获得运行授权。普通 Cursor/PI 配置与 Herdr、产品 PI Runner 各自独立。
|
||||
@@ -0,0 +1,88 @@
|
||||
# Subagent 模型分配配置
|
||||
|
||||
config_revision:`subagent-models-2026-09-24-r1`
|
||||
|
||||
owner:用户;维护执行者:当前任务主 Agent。
|
||||
|
||||
decision_state:`approved`(本会话确认);integration_state:`merged`;execution:`enforced`(本执行器已验证的配置/租约/工具/进程边界);阶段审批仍为 manual。
|
||||
|
||||
**这是模型分配的唯一配置文档。** 用户调整下列表格;主 Agent 每次派发前读取,并把解析结果写入[派发记录](templates/subagent-stage-record.md)。`scripts/pi_subagents.py` 已直接解析本文件,Cursor MCP 提供角色预览、派发与结果查询;每次新派发读取配置,旧请求保留旧摘要。实测与边界见[运行说明](2026-09-24-pi-subagent-executor.md)和[报告](../test-reports/2026-09-24-pi-executor-test-report.md)。完整流程见[协作规范](2026-09-24-subagent-workflow-standard.md)。
|
||||
|
||||
## 1. 日常调整入口
|
||||
|
||||
| 想调整什么 | 修改位置 | 生效方式 |
|
||||
|---|---|---|
|
||||
| 某角色的默认模型 | §3 对应角色的“默认模型”列 | 修改后递增 config_revision;下一次派发读取 |
|
||||
| 复杂任务的升级去向 | §3 “升级角色”列 | 升级时保留原报告与原因;以目标角色重新派发 |
|
||||
| 启停某角色 | §3 enabled 列 | false 时不自动派发;引用该角色的升级关系须同时调整;必需职责暂停或显式重新分配,不能跳过门禁 |
|
||||
| 允许使用的 provider/model | §2 模型池 | 使用本机精确 ID;新增模型需用户明确调整授权范围并更新程序硬边界校验 |
|
||||
| 并发量、失败处理 | §4 | 主 Agent 按配置与任务实际资源取更严格边界 |
|
||||
| 只改本次任务 | 在任务主记录写 override | 记录用户指令、角色、原值/新值、期限;不改全局默认 |
|
||||
|
||||
文档中表格值为配置;其他文件只引用本文件,不重复维护模型名。用户可以直接编辑,也可以说“把本任务 code_review 改用 qwen_max”或“以后 report 都用 glm_full”。后者需按仓库 worktree/受控集成流程保存。
|
||||
|
||||
字段规则:enabled 只取 true/false;默认模型引用 §2 的 alias;升级角色引用 §3 的 role_id,或 none;缺字段、未知 alias、循环升级、角色越权时停止该派发并报告错误,不自行猜测模型。
|
||||
|
||||
## 2. 允许的模型池
|
||||
|
||||
主会话:**Cursor,模型选择 Auto**;工程子任务:**gmktec 本机 PI CLI**。这份配置不改变 Cursor UI 模型开关、PI 全局默认设置或产品 PI Agent Runner。
|
||||
|
||||
| alias | provider | model(精确 ID) | 使用限制 |
|
||||
|---|---|---|---|
|
||||
| qwen_max | qwen-token-plan-cn | qwen3.8-max | 可分配分析、规划、报告与复核 |
|
||||
| qwen_flash | qwen-token-plan-cn | qwen3.8-flash | 默认检索、资料与初稿;复杂任务升级 |
|
||||
| glm_full | zai-coding-cn | glm-5.3 | 默认评估、独立审查和复杂归因 |
|
||||
| glm_flash | zai-coding-cn | glm-5.3-flash | 默认测试执行与证据收集;复杂判断升级 |
|
||||
| minimax_aux | minimax-cn | MiniMax-M3 | 默认停用,仅明确启用后用于易核验辅助任务;不能承担关键判断 |
|
||||
|
||||
本机 provider 是 qwen-token-plan-cn;用户提到的 qwen-token-plan 在此明确映射到该通道。相同模型名出现在其他 provider 不构成可替换授权。M3 不进入规划、代码审查、根因裁决、最终验收或主力自动备用链;需要改变这些限制时由用户明确修订本节。
|
||||
|
||||
目录核对:2026-09-24,通过本机 pi 的离线 --list-models 核实以上五个组合。存在于目录不等于远端连通、工具调用、性能和任务质量已实测。
|
||||
|
||||
## 3. 角色路由表
|
||||
|
||||
代码实施与修复固定由 **Cursor Auto** 承担;下表只路由 PI 子任务。PI 不修改产品代码或测试源码,所需修复/新测试交回 Cursor。
|
||||
|
||||
| role_id | 工作 | enabled | 默认模型 | 升级角色 | 执行边界 |
|
||||
|---|---|---|---|---|---|
|
||||
| research | 检索、代码定位、资料摘录、需求初稿 | true | qwen_flash | planning | 只读;结论回传主 Agent |
|
||||
| planning | 需求分析、方案制定、复杂问题综合分析 | true | qwen_max | none | 只读;保留假设与依据 |
|
||||
| requirements_review | 独立评估需求与影响 | true | glm_full | none | 新上下文;不代替用户取舍 |
|
||||
| plan_review | 独立方案审查 | true | glm_full | none | 不自审自己编制的方案 |
|
||||
| code_review | 代码审查与回归风险检查 | true | glm_full | none | 冻结 diff;不修改被审内容 |
|
||||
| diagnosis | 复杂失败归因、跨模块机制分析 | true | glm_full | none | 只读分析;复现操作由 test_run 在授权环境执行 |
|
||||
| test_run | 按已批准验证计划执行测试、收集证据、初步分析 | true | glm_flash | diagnosis | 仅批准命令、测试产物与环境;不修改源码 |
|
||||
| acceptance_check | 按既定 AC 执行检查、核对真实证据 | true | glm_flash | diagnosis | 不代签最终验收;涉及业务取舍交 acceptance_owner |
|
||||
| stage_notes | 阶段记录与报告初稿 | true | qwen_flash | report | 忠实整理原证据;主 Agent 持锁落盘 |
|
||||
| report | 最终报告、复杂材料综合 | true | qwen_max | none | 汇总不能改写原始失败或推导未验证的 PASS |
|
||||
| auxiliary | 格式整理、清单提取等易核验工作 | false | minimax_aux | none | 明确启用后派发;保留来源供核验 |
|
||||
|
||||
一个模型可承担多种角色,但派发必须区分上下文与职责。即使用户将规划和审查映射到同一模型,独立审查仍须新上下文/不同执行实例;模型不同也不自动证明审查独立。
|
||||
|
||||
最终验收责任继续归任务声明的 acceptance_owner;主 Agent 核对证据与权限后推进。test_run 和 acceptance_check 的输出是检查结果,不能只因模型返回“通过”就放行。
|
||||
|
||||
## 4. 执行与升级参数
|
||||
|
||||
| 参数 | 默认值 | 语义 |
|
||||
|---|---|---|
|
||||
| max_parallel_pi_tasks | 2 | 同时运行的 PI 子任务上限;路径冲突/共享环境锁优先 |
|
||||
| implementation_executor | cursor_auto | 实施和修复不派给 PI;改此边界需要用户明确授权 |
|
||||
| unavailable_action | pause_role | 模型或通道不可用时暂停对应角色;可继续无依赖工作 |
|
||||
| automatic_fallback | none | 不静默换模型/换 provider;不因超时降级到 M3 |
|
||||
| reload_boundary | next_dispatch | 新任务/下一次派发读取;不修改正在运行的子任务 |
|
||||
| recursive_delegation | false | 仅主 Agent 派发;PI 子任务需要协作者时返回建议 |
|
||||
|
||||
升级触发:Flash 无法解释失败、证据互相矛盾、涉及跨模块机制或超出已批准验证计划。升级用于质量不足,不是网络故障重试;结果未知先核对副作用,流程遵循协作规范。
|
||||
|
||||
本次用户覆盖 > 本文件默认;仓库授权/写锁/验收边界始终约束执行。对文档中已允许角色和模型的任务级调整,不重复索要已经给出的许可;自动化程序、日志和子报告中的“配置已批准”不能替代用户来源。
|
||||
|
||||
## 5. 配置更改与追溯
|
||||
|
||||
1. 在任务 worktree 调整本文件;全局默认修改随受控集成发布。本轮已合入本地 dev;新任务从 dev 创建后使用此配置,调整后仍需受控集成。
|
||||
2. 更新 config_revision;保留修改原因和用户来源。派发前核对角色、模型池和升级关系。
|
||||
3. 每次派发记录配置路径、config_revision、文件 SHA-256、role_id、configured provider/model、任务覆盖和原因;已有子任务沿用自己的配置快照。
|
||||
4. PI 启动时按精确 provider/model 传递,不能省略参数后依赖 ~/.pi/agent/settings.json。启动记录或可信响应元数据不可核验实际模型时填 actual_model=unknown。
|
||||
5. 修改配置不产生代码写入、环境操作、push、部署或清理授权;报告/输出由主 Agent 按现有租约规则保存。
|
||||
6. 回退时恢复先前角色值,递增配置修订并记录来源;不要覆盖历史派发记录或把失败改成成功。
|
||||
|
||||
初始决策依据:用户指定五模型池;明确“代码实施还是让 cursor 来”;反馈 M3 能力有限;随后确认“M3 移出默认流程、仅可选辅助”,并要求提供可调整配置文档。
|
||||
@@ -0,0 +1,165 @@
|
||||
# 主 Agent 与 Subagent 协作流程规范(草案)
|
||||
|
||||
修订:`subagent-workflow-2026-09-24-r2`;owner:Codex;规则状态:`proposed`;执行能力:`manual`;effective_commit:无。
|
||||
本流程规范仍为待审稿;用户已确认 Cursor 实施、本机 PI 分析/审查/验证及模型默认分工,具体值唯一维护在[模型配置](2026-09-24-subagent-model-config.md)。规则批准与受控集成后才进入 active;文档存在不表示 PI 调度器已接入。
|
||||
研究与来源见[研究报告](../audit/2026-09-24-subagent-workflow-research.md),本次授权及交付状态见[任务](short-term/2026-09-24-subagent-workflow-standard.md)。
|
||||
|
||||
## 1. 目标、适用范围和权威
|
||||
|
||||
用户在 Cursor 主会话保持 Auto;Cursor 负责主协调、代码实施和修复,通过 gmktec 本机工程 PI CLI 委派分析、审查、测试和报告。每阶段产生可恢复记录。此配置不自动适用其他客户端或 Herdr。
|
||||
|
||||
本规范只定义角色、阶段、交接和证据引用。授权边界沿用 [AGENTS](../../AGENTS.md),写锁/候选合并/环境/清理沿用 [worktree 操作规范](2026-09-21-agent-worktree-workflow.md),测试层级沿用[验证契约](2026-09-21-validation-contract.md),问题闭环沿用[既有规范](2026-09-23-issue-learning-workflow.md)。不建立第二套测试门禁。
|
||||
|
||||
普通 Cursor 会话不启用 Herdr 角色和固定模型路由;只有明确使用 Herdr 时适用其专门规范。工程 subagent 与产品 PI Agent Runner 分开记录,前者的执行不能替代后者的验收。
|
||||
|
||||
## 2. Auto、授权和推进规则
|
||||
|
||||
- **模型策略**:主会话选择 Auto;PI 子任务按[模型配置](2026-09-24-subagent-model-config.md)的角色、provider 和 model 派发。Cursor 原生 subagent 的 model: inherit 方案已被用户后续选择替代,本规范不以 .cursor/agents 实现 PI 路由。
|
||||
- **能力核验**:首次接入、客户端升级或模型行为异常时,记录客户端版本、角色可发现性、派发 ID、工作目录、配置模型策略及可观察的实际模型;不可见时写 `actual_model=unknown`。不得从自我介绍推断模型。
|
||||
- **证据边界**:记录配置指定值与可核验的实际模型;未核验不声称模型调用成功。模型多样性不替代独立上下文和证据。
|
||||
- **授权策略**:Auto 只表示模型选择,不表示自动授权 shell、外部写入、合并、部署、推送或删除。任务开始记录已有授权,后续不重复询问相同范围。
|
||||
- **默认确认点(待用户采纳)**:需求形成、评估、方案编制可连续进行;方案可审后,一次确认方案与实施范围。已明确授权按该方案端到端执行,则该确认已经满足。只有范围/环境/外部副作用扩大、破坏性动作或需要用户作业务取舍时再确认。
|
||||
- **验收人**:需求阶段明确 acceptance_owner。技术验收检查可由获授权 acceptance_check 执行;产品效果/业务取舍需要用户判定时,技术通过后保留 `acceptance=pending`,不由 Agent 代签。用户预先委托按明确客观标准验收时,记录委托来源和证据即可。
|
||||
- 仅请求研究/方案的任务交付可审产物后结束。实现、运行验证、合并等阶段逐项写 `not_applicable + 原因`,不为了流程齐全擅自执行。
|
||||
|
||||
## 3. 标准流程
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[建场与授权记录] --> B[形成需求和验收标准]
|
||||
B --> C[评估需求与影响]
|
||||
C --> D[制定方案和验证计划]
|
||||
D --> E{实施授权是否满足}
|
||||
E -->|是| F[实施和开发自测]
|
||||
E -->|否| P[交付可审方案]
|
||||
F --> G[独立代码审查]
|
||||
G -->|需修改| F
|
||||
G -->|通过| H[冻结交付版本并验证]
|
||||
H -->|失败| F
|
||||
H -->|通过| I[构造候选并验证合并结果]
|
||||
I -->|通过| J[受控合入 dev]
|
||||
J --> K[按授权部署与运行验收]
|
||||
K -->|失败| R[保留现场并修复或交接]
|
||||
R --> F
|
||||
K -->|通过或不适用| L[确认交付并归档证据]
|
||||
L --> M[owner退出后独立复查清理]
|
||||
```
|
||||
|
||||
测试计划在方案阶段形成;自测贯穿实施;独立审查和必要测试必须覆盖最终版本。清理安排在验收与证据保存之后。合并前的工程验证与合并后的运行验收分别报告。
|
||||
|
||||
### 阶段、产物和放行条件
|
||||
|
||||
每行都是阶段记录要求,不要求每行一个文件。记录使用[阶段模板](templates/subagent-stage-record.md)。
|
||||
|
||||
| 阶段 | 责任与输入 | 最小产物 | 放行条件 / 失败去向 |
|
||||
|---|---|---|---|
|
||||
| S0 建场 | 主 Agent;用户请求、当前规则、Git/认领状态 | task 主记录:目标、授权、基线、写路径、环境、交付终点、policy_revision | 允许范围明确;持久成果在任务 worktree;按现行入口登记 |
|
||||
| S1 形成需求 | Cursor 与用户,可委派 research/planning;原始描述 | 需求记录:用户场景、范围/非目标、R-ID、AC-ID、优先级、验收人 | 可验证预期明确;影响方案的歧义解决,小型假设标注 |
|
||||
| S2 评估需求 | requirements_review;S1 和当前证据 | 评估报告:现状差距、替代方案、依赖、风险、复杂度和建议 | 结论为 proceed / revise / defer;高风险未知有验证路径;revise 回 S1 |
|
||||
| S3 制定方案 | Cursor 协调 planning 编制、plan_review 独立复核;S2 | 方案:改动位置、接口/数据影响、实施依赖、写者、验证矩阵、恢复方案;附方案审查结论 | AC 映射到验证项;必要权限齐备;授权不足交付方案等待;设计疑问回 S2 |
|
||||
| S4 实施与自测 | Cursor;已授权方案 | 实施记录:变更、提交、偏差、自测与失败记录 | 实现满足方案且自测有证据;范围变化回 S1/S3;不得降低 AC 迁就实现 |
|
||||
| S5 独立代码审查 | code_review;需求/方案、base/head、完整差异 | 审查报告:范围、审查者、严重度、位置、依据、处置与复核 | 无未解决阻断项;修复回 S4,变更后的代码需复核 |
|
||||
| S6 交付验证 | test_run;冻结版本、AC、验证契约 | 测试报告:预期用例、实际命令/输入/输出、环境、SHA、PASS/FAIL/SKIP/未运行 | 适用必需项均通过;SKIP/基础设施失败保留阻塞;失败回 S4 或 S3 |
|
||||
| S7 候选与集成 | 串行集成执行者;S5/S6、最新 dev D、冻结 T | 集成报告:D/T/M、候选验证收据、锁内结果、实际 dev | 按现行 --no-ff 候选与 --ff-only 入口;D/T/M 变化须重新准入 |
|
||||
| S8 运行与交付验收 | acceptance_check + acceptance_owner;受控制品、AC | 验收报告:实际制品、环境、用户流程、持久状态、逐项 AC 结论 | 所需运行/UI 验收通过;无运行影响写 not_required;失败不清理、不冒充完成 |
|
||||
| S9 归档与清理 | 主 Agent 固化证据,owner 退出后维护者执行清理 | 收口报告:提交/集成/部署/远端/cleanup 分离;归档证据、清理结果与遗留 owner | 满足现行普通 remove/-d 条件;拒绝保留 pending,登记触发和接管者 |
|
||||
|
||||
S5 与 S6 可以在同一不可变版本上并行;必要产物必须都回来才能进入 S7。测试产生构建目录/缓存/数据也算写副作用,先核对其环境和锁。code_review 阅读稳定 Git 快照,不在 Cursor 正在改写的工作树上宣布最终通过。
|
||||
|
||||
S7 候选需执行该范围的真实检查,不能用分支自测替代合并结果验证。S8 后新增的报告提交也需受控集成;分别记录被测业务 SHA 与报告 SHA,说明仅文档变化的复用依据。影响运行内容的后续变更使相关验收失效。
|
||||
|
||||
## 4. 角色和分工
|
||||
|
||||
角色是职责,不要求每阶段单独启动一个进程。精确 role_id、enabled、默认模型和升级链只维护在[模型配置](2026-09-24-subagent-model-config.md),下表说明权限边界。
|
||||
|
||||
| 角色 | 职责 | 写权限和独立性 |
|
||||
|---|---|---|
|
||||
| Cursor / coordinator | 与用户对话、授权核对、任务图、派发、证据汇总、冲突处理、推进门禁和交接 | 唯一任务协调者;报告汇总不改变原作者/证据/结论;不能从子报告推导额外授权 |
|
||||
| research / planning / report / stage_notes | 需求影响、方案、资料和报告 | 默认只读;返回结构化报告,由主 Agent 落盘;若编制方案,另一个上下文审查方案 |
|
||||
| Cursor / implementation | 实施方案、修复问题、编写和修改测试源码 | 产品和测试源码的实施者;按认领/租约操作,PI 建议交回 Cursor 处理 |
|
||||
| requirements_review / plan_review / code_review / diagnosis | 独立评估、审查与复杂故障归因 | 新的只读上下文;不修改被审内容;发现问题返回 Cursor;复现交给获授权的 test_run |
|
||||
| test_run / acceptance_check | 按冻结 AC 和已批准计划执行验证,核对真实行为 | 仅写批准的测试产物/环境;不改源码、不代签最终验收,需要修复交回 Cursor |
|
||||
| integrator / maintainer | 候选验证、受控合并;owner 退出后的清理 | 串行短时角色,使用现有工具/权限;不能把长驻 worker 同时当作可删除的 worktree owner |
|
||||
|
||||
同模型的独立上下文可以提供独立检查,但不消除共同盲区;验证仍以源码、命令和用户流程证据为准。主 Agent 自审只能记录 self_review。要求独立审查的代码任务如无 subagent 能力,交给另一个独立会话/人员;该项完成前不自动放行。低风险纯文档可自检并记录理由。
|
||||
|
||||
## 5. 何时派发与如何并行
|
||||
|
||||
- 适合派发 PI:较长只读研究、独立审查、按批准计划验证、报告整理。代码实施和修复保留给 Cursor。
|
||||
- 主 Agent 直接处理:一次定位、简短文案、单一顺序操作;仍留下对应阶段记录。无需为了覆盖阶段机械启动九个 Agent。
|
||||
- 并发上限及递归委派规则以模型配置为准;资源不足串行。它是项目预算,不是平台上限;子 Agent 发现进一步分解需求先返回建议。
|
||||
- 先画依赖再并行;有先后依赖的任务等待前置证据。有相同文件、公共 lockfile、路由、迁移号或共享环境的写任务不能同时认领。
|
||||
- 同一任务 worktree 的源码写者为 Cursor,PI 只读任务读取冻结快照;只读报告由 Cursor 持锁保存。PI 验证涉及产物/环境写入必须在有效 agentctl supervisor 下运行;无法保证时停止执行并报告条件缺失。
|
||||
- 若另行开展多 Cursor 并行实施,仍须独立登记 worktree,各自从明确 dev SHA 创建;父子关系用 parent_task_id/subtask_id 关联。此条不授权 PI 实施代码。
|
||||
- 父任务汇总子任务成果,源码仍由 Cursor 实施。涉及测试产物写入的子任务登记独立操作 ID/路径;只读子审查复用父任务文档,不重复创建任务链。子分支结果通过现行候选集成流程交付;不能由 Cursor 的自动隔离/自动合并绕过本仓注册和准入。
|
||||
- 有后台任务时,主 Agent 可继续独立工作,但不得在结果未回收时发布依赖它的 PASS、合并或清理。各子任务的工具可用性不代表授权可用性。
|
||||
|
||||
## 6. 派发、回传与失败处理
|
||||
|
||||
每次派发至少包含:
|
||||
|
||||
1. parent_task_id、subtask_id、role_id、具体目标、输入版本(需求/方案/代码 SHA);配置路径、config_revision、文件 SHA-256、解析后的 provider/model 和任务覆盖依据。
|
||||
2. 需要读的规范和证据、已有用户授权来源、明确的非目标。
|
||||
3. 工作目录、允许写路径、环境、mutex/租约执行方式;只读者明确只读。
|
||||
4. 完成条件、输出格式/报告路径、需要验证的 AC;子 Agent 不依赖未传入的主会话历史。
|
||||
5. 预算(时间或步骤)、进度回传点、失败/超时和副作用核对方式。
|
||||
|
||||
回传至少包括:执行身份/PI run_id、配置版本与指定/实际模型、实际输入版本、结果与证据、变更文件/提交、实际命令与环境、结论、缺项/风险、遗留进程/产物。主 Agent 校验路径、版本和证据后标记 accepted;子 Agent 自报 done 只表示执行结束。
|
||||
|
||||
- 分开记录 run_status(running/succeeded/failed/cancelled/unknown)与 verdict(pass/changes_required/blocked/not_applicable),不可把退出成功等同质量通过。
|
||||
- 超时/失联先检查进程、worktree、Git 和外部副作用;结果未知时保留 unknown,不同时重派同一写任务。纯只读且确认无副作用的失败可有限重试,并保留原记录。
|
||||
- 审查/验证角色有异议时,主 Agent 依据原需求和证据裁决。能修复则回 S4;需要业务取舍则向用户汇总一个关键问题,不以多数投票覆盖阻断证据。
|
||||
- 连续两轮修复仍未解决同类阻断时,停止机械重试,回 S2 重查机制/测试前提;授权内可继续研究。不得为放行删除失败用例或降低 AC。
|
||||
- 用户中断、客户端退出、上下文压缩时,先固化阶段、版本、未回收子任务、owner 和接管条件;恢复后从首个未满足门禁继续,不能整条流程重跑或直接跳到收口。
|
||||
|
||||
## 7. 文档与报告契约
|
||||
|
||||
“一步一记录”,无需“一步一文件”。现有文件优先复用,原始证据只存一处:
|
||||
|
||||
| 任务类型 | 最小文档集合 |
|
||||
|---|---|
|
||||
| 信息问答,无持久成果或运行副作用 | 对话答复 |
|
||||
| 小型规范/研究/低风险变更 | 一个 task 或分析主文档,含适用阶段、验证与交接 |
|
||||
| 标准功能/缺陷修复 | task + 方案 + 报告;评估/实施/审查/测试/验收可为清楚分段 |
|
||||
| 跨模块、迁移或部署 | task + 必要 plan + 分开的审查/测试/验收证据;handoff 仅在独立信息有价值时拆分 |
|
||||
|
||||
每份阶段记录包含 stage_id、输入版本、producer、reviewer/独立性、decision、证据链接、缺项和下一步。需求用 R-ID,验收用 AC-ID,测试用 T-ID;报告提供 R → AC → 改动 → 审查 → 测试 → 运行验收映射,避免仅列“文档已生成”。
|
||||
|
||||
路径沿用 .doc taxonomy:任务在 ops/short-term,研究/审查在 audit,方案在 remediation 或既有 ops 主文档,独立测试/验收在 test-reports,附件在其 assets。只读 subagent 由主 Agent 保存原始结论及必要摘录,标明“由主 Agent 转存”与 agent_id;不伪造子 Agent 已写文件。
|
||||
|
||||
任务 status 继续只有 planned/in_progress/blocked/done/cancelled;phase 与 review_state、integration_state、deployment、cleanup、remote_sync、acceptance 独立记录。done 取决于授权交付终点。清理待办不扩充任务状态,但必须有人接管。需求验收 pending 时,若验收属于授权交付终点,任务不能 done。
|
||||
|
||||
## 8. Cursor → 本机 PI 接入(任务分支已实现)
|
||||
|
||||
### 配置与能力边界
|
||||
|
||||
用户已明确选择 Cursor Auto 主协调和实施、gmktec 本机 PI 承担子任务;原 r1 的 Cursor 原生 .cursor/agents + inherit 方案废止,历史研究保留说明。当前[模型配置](2026-09-24-subagent-model-config.md)可人工调整,由执行器每次派发读取;不是 PI 原生配置格式,不改变 PI 全局模型设置。CLI/MCP 接入与限制见[运行说明](2026-09-24-pi-subagent-executor.md),实际验证见[报告](../test-reports/2026-09-24-pi-executor-test-report.md)。
|
||||
|
||||
PI 模型和角色路由以配置文档为唯一来源。主 Agent 根据任务读取 role_id,显式传入 provider/model、独立会话、输入版本、工作目录与工具范围,收取结果后按本规范形成阶段记录。不能把主会话可用工具全部自动授予子任务。
|
||||
|
||||
- 只读研究/审查不需要 bash/edit/write;后续接入时显式限制工具,并核对扩展是否引入额外能力。
|
||||
- 测试角色需要执行批准的命令并产生缓存/产物,不能假称只读;将测试工作目录、数据和环境放在批准范围内,使用既有 agentctl 租约。
|
||||
- PI 报告由主 Agent 持锁落盘;PI 不修改业务代码或测试源码。将诊断建议交回 Cursor 实施。
|
||||
- 模型不可用、实际模型不符、配置缺失或未知结果遵循配置和 §6,不隐式换通道或降级。
|
||||
- 普通本机 PI 调度不复用 Herdr 自动审批/模型预算;产品 PI Runner 仍按目标环境批准配置独立验收。
|
||||
|
||||
### 后续接入步骤与验收
|
||||
|
||||
| 步骤 | 变更 | 必需证据 |
|
||||
|---|---|---|
|
||||
| A 文档配置 | 已确认分工,维护模型配置/派发模板;流程整体另按规范登记 | 默认值与用户选择一致;修改可追溯;未合入前不称全仓 active |
|
||||
| B 消除旧规则冲突 | 修订 Cursor 测试规则副本为验证契约指针 | 相关 ISSUE 单独修复验证;本次不改变 Runner |
|
||||
| C 实现派发入口 | 已实现 CLI + 项目 MCP;本地任务分支代码 69ffaa67 | 配置/租约/模型/快照/结果校验与异常回归已验证;dev 集成另记 |
|
||||
| D 实机试运行 | 小型文档任务和受控代码任务(代码由 Cursor 写) | Auto 不需手动切模型;PI 角色/模型/run_id/证据可追溯;不冒充真实产品 PI |
|
||||
| E 异常演练 | 同路径写冲突、PI 失联、必需测试缺项、dev 变化、验收失败、清理拒绝 | 正确暂停/升级;保留失败证据 |
|
||||
| F 工具门禁 | 据试运行决定是否增加阶段校验/hook | 实现和真实负例验收后才将相应能力标 enforced |
|
||||
|
||||
接入验收 V1–V10:V1 Cursor Auto 与配置指定 PI provider/model;V2 授权/需求上下文传递;V3 独立只读审查与报告转存;V4 租约内测试;V5 输入 SHA 变化后复核;V6 写冲突拒绝;V7 缺项不合并;V8 验收失败保留现场;V9 清理拒绝有 owner;V10 中断后恢复。新增 V11:修改配置只影响下一次派发、记录 hash;V12:M3 停用/越权路由及未知 alias 被拒绝。本轮执行器已完成 173 项工程回归与真实 Cursor CLI→MCP→PI 验证,覆盖及未覆盖项以测试报告为准;这不是宣称全部 S0–S9 审批、产品 UI/共享环境或清理已自动执行。
|
||||
|
||||
### 日常使用与调整
|
||||
|
||||
用户只需保持 Cursor Auto,说明任务目标与授权终点;主 Agent 读取本规范和模型配置,按需要派发 PI。修改默认分工只编辑模型配置文档;临时调整写入任务 override,不静默改全局默认。流程、模型配置和某任务授权是三个不同对象。
|
||||
|
||||
用户可以授权“按已确认方案执行到 local dev 集成与 dev 验收”;该授权不会自动包含 push 或晋升 test/main。验收后归档证据,当前 owner 退出后再由独立维护者复查清理。
|
||||
|
||||
回退:调度入口或权限不满足时暂停相应 PI 阶段,保留现场与证据,交回 Cursor 处理;不能以主 Agent 自审替代要求的独立审查。修复接入后再验证。
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
title: "U1 基线清单与主干同步记录"
|
||||
date: 2026-09-29
|
||||
task_id: multi-repo-design-2026-09-28
|
||||
---
|
||||
|
||||
# U1 基线盘点与同步结果
|
||||
|
||||
## 备份
|
||||
|
||||
- 全量 bundle:`~/projects/agent-system-all-2026-09-29.bundle`(193M,--all,verify 通过)。
|
||||
|
||||
## 主干同步(D1)
|
||||
|
||||
- 本地 dev(1bb48030)→ 远端 dev:fast-forward `fabd85a6..1bb48030`(337 提交),无分叉无重写。
|
||||
- 补推 11 个缺失 tags(rc-v1.0.0-beta.1–7、rc-v1.1.0-beta.4–7、backup/pre-rewrite-2026-09-13)。
|
||||
- test/main 未动(test=0e4b111,main=210fe4a)。
|
||||
|
||||
## 分支清理(D5)
|
||||
|
||||
- 删除已合入 dev 的 25 个远端陈旧分支(chore/、docs/、feature/pu*、fix/nightly-* 等)。
|
||||
- 保留:dev/test/main、6 个未合入待审分支(integrate-agent-governance-config、
|
||||
integrate-coordination-db-daemon-impl-closeout、promote-task-bubble-bind-test、
|
||||
remove-herdr-agent-settings、software-project-bootstrap、squad-missing-target-retry,
|
||||
均为 2026-09-14~23 遗留,后续逐个审阅收口)、
|
||||
**feature/u9u12-keys-rollout-2026-09-25(活跃 worktree 任务,已推送远端保存)**。
|
||||
- 清理后远端共 10 分支。
|
||||
|
||||
## Worktree 状态(全部保留)
|
||||
|
||||
| 目录 | 状态 | 处置 |
|
||||
|---|---|---|
|
||||
| .worktrees/u9u12-keys-rollout-2026-09-25 | 活跃 git worktree,分支 feature/u9u12-keys-rollout-2026-09-25(f9ce7719),干净 | 保留;分支已推远端 |
|
||||
| .worktrees/full-system-browser-e2e-2026-09-26 | 非 git worktree,仅含 .doc 残留 | 保留不动 |
|
||||
| .worktrees/promote-rc-beta6-closeout-2026-09-28 | 非 git worktree,仅含 .doc 残留 | 保留不动 |
|
||||
|
||||
## 运行制品与治理状态快照
|
||||
|
||||
- 树内跟踪 *.test 二进制 4 个(docgov/notification/projectinstance/storage)——U6 阶段以普通提交移除,不重写历史。
|
||||
- 锁库(.locks/state.sqlite,只读快照):tasks=417、runs=1934、receipts=147、audit_ledger=26682;
|
||||
agentctl status 若干 busy 项 supervisor_alive=dead(陈旧),未清理——U2a 处理,本轮只记录。
|
||||
- 工作区唯一脏文件 `.cursor/rules/agentctl-mandatory.mdc`(删除)已恢复(D6),随 U2a 再删。
|
||||
|
||||
## 远端仓库现状(同步后)
|
||||
|
||||
- Agent-System:dev=1bb48030(=本地),10 分支,无保护(U2b 设置)。
|
||||
- Development-Manager:dev=main=8867e38,本地一致干净。
|
||||
- 4 空仓(Squad/Documents/Guidelines/Releases)原样;Releases-Internal(private)待 U6a 前创建。
|
||||
- governance-drill-2026-09(演练仓,private):已完成 U1.5 全部门禁验证,保留至 U2b 收口。
|
||||
|
||||
## U2b 分支保护状态(2026-09-29 追加)
|
||||
|
||||
PR #1 合并(4d716bcd,agent-bot 作者 / weichen 批准合并)后,Agent-System 启用保护:
|
||||
|
||||
| 分支 | 直推 | 白名单直推 | 合并 | required checks |
|
||||
|---|---|---|---|---|
|
||||
| dev | 禁 | weichen | 仅 weichen 经 PR(需 1 非作者批准+陈旧撤销+最新基线) | CI / go-vet、CI / backup-restore-drill、CI / web (pull_request) |
|
||||
| test | 禁 | weichen | 仅 weichen 经 PR | 无(晋升验证另行补) |
|
||||
| main | 禁 | weichen | 仅 weichen 经 PR | 无 |
|
||||
|
||||
apply_to_admins=true(admin 不旁路)。首个全绿 CI 轮:go-vet ✓、backup-restore-drill ✓、web ✓;
|
||||
短测存量失败按 KTD14 报告不阻断,issue #2 跟踪。
|
||||
|
||||
本地治理钩子(agentctl 强制 with/收据)在主工作树已停用(chmod -x,内容保留);
|
||||
远端准入权威自此为 Gitea 原生保护。本地编辑/提交零 agentctl 依赖。
|
||||
edit A 05:07:06
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
title: "U2 治理交接收口:Gitea 原生门禁取代本地 agentctl 治理"
|
||||
date: 2026-09-29
|
||||
task_id: multi-repo-design-2026-09-28
|
||||
supersedes: agentctl-mandatory 客户端规则与本地租约/收据/候选集成流程
|
||||
---
|
||||
|
||||
# U2 收口记录
|
||||
|
||||
## 交接内容
|
||||
|
||||
| 旧机制(agentctl 本地治理) | 新权威 | 状态 |
|
||||
|---|---|---|
|
||||
| pre-commit/reference-transaction 本地租约与收据 | Gitea 受保护分支(dev/test/main) | 旧钩子文件已删除(原 chmod 停用,现正式退役) |
|
||||
| `agentctl with`/SQLite 写前置 | 无(普通 Git) | 编码流程零 agentctl |
|
||||
| `docs apply` 共享文档 CAS | PR 版本历史 + CI 一致性检查 | CURRENT/MATRIX 转只读快照 |
|
||||
| 候选 `validate`/`queue enqueue`/`integrate` | PR + 必需 CI(go-vet、backup-restore-drill、web)+ 非作者批准 | 旧本地 dev 推进入口退役 |
|
||||
| 需求重叠 catalog 硬门禁 | 降为建议(PR 审核中人工判断) | 不再阻塞写入 |
|
||||
| 收口必跑 cleanup report / docs drift | 移至维护任务/按需 | 不再是会话前置 |
|
||||
|
||||
保留不变的硬边界:凭证/秘密防护(新增 CI secrets 扫描)、共享环境写授权、
|
||||
破坏性操作授权、他人现场保护、证据诚实、产品 IAM/文档职责/DB 事务(产品侧,与本交接无关)。
|
||||
|
||||
## 协作模型(实测验证)
|
||||
|
||||
- 编码 Agent = `agent-bot`(作者):功能分支、提交、建 PR。
|
||||
- 用户 = `weichen`(审核者+合并者):批准、合并;白名单直推保留(不破坏既有习惯)。
|
||||
- Gitea 1.27.3 硬禁止自批准 → 非作者审核由平台强制,非自觉约定。
|
||||
- 完整闭环已跑通:PR #1(U1 文档 + CI 修复)bot 作者 → CI 绿 → weichen 批准 → 合并 4d716bcd。
|
||||
|
||||
## 验收证据
|
||||
|
||||
| 场景 | 结果 |
|
||||
|---|---|
|
||||
| V19 两个独立 clone 同路径并行编辑、各自提交 | 双方均成功,无全局锁牵连(本日实测,分支已清理) |
|
||||
| V20 停 daemon/无本地治理 → 本地开发 | 本会话全部提交零 agentctl 调用;原仓钩子已删除 |
|
||||
| V23 旧入口不能推进远端 | agent-bot 直推 dev 被拒(N6);无批准/陈旧分支/缺 CI 的合并在演练仓全部被拒(N3–N5) |
|
||||
| V26 完整修复→测试→提交→PR→合并零 agentctl | PR #1 全流程即证据;CI 必需检查绿后合并 |
|
||||
| 白名单非破坏 | weichen 直推 dev 放行(P1,4d716bcd..9504b624) |
|
||||
|
||||
## 遗留与后续
|
||||
|
||||
- 短测存量失败(环境依赖用例)→ issue #2,修绿后并入必需门禁。
|
||||
- Development-Manager 中 agentctl 的部署/发布/恢复角色重写(KTD13 裁剪矩阵)→ 后续任务,编码流程已不依赖。
|
||||
- 锁库 `.locks/state.sqlite` 与历史任务记录冻结为只读证据,不再作为权威。
|
||||
- 演练仓 `governance-drill-2026-09` 保留至 U6a 发布链路验证后删除。
|
||||
- 规范文档链(worktree-workflow、policy-registry、validation-contract 等)保留为历史参考;AGENTS.md/PROJECT.md 已按新模型改写并在本 PR 生效。
|
||||
@@ -0,0 +1,41 @@
|
||||
---
|
||||
title: "U6a 单文件内部 RC 冒烟记录(首个干净环境验证)"
|
||||
date: 2026-09-29
|
||||
task_id: multi-repo-design-2026-09-28
|
||||
binary: agent-system @ 5d961147(33M,CGO_ENABLED=0,内嵌 web/dist)
|
||||
---
|
||||
|
||||
# 结论:U6a 单文件冒烟通过(本地 RC,未发布)
|
||||
|
||||
按 KTD14/V9/V27 部分场景,在**无源码目录**的一次性环境验证:
|
||||
|
||||
| 场景 | 结果 |
|
||||
|---|---|
|
||||
| 构建 | build-single-binary.sh:web 构建(67×2 预压缩资产)+ go build,33M |
|
||||
| `config check`(干净目录) | 通过;DB 目标来自进程 env;秘密仅 `<set>/<unset>` |
|
||||
| `config explain` | instance_id 正确标注 process-env 层 |
|
||||
| 实例引导 | instance-marker.json(rc-smoke,0600)+ instance.lock 创建 |
|
||||
| **内嵌迁移** | 一次性隔离 pgvector 库从零迁至 **schema_version 78**(goose 内嵌链,无源码目录) |
|
||||
| 服务启动 | 监听 :5590,/api/v1/health:database_ready:true、schema_ready:true、task_store_ready:true |
|
||||
| **内嵌 UI** | GET / 返回 SPA index.html(200)——go:embed dist 生效 |
|
||||
| 误重复启动 | 第二进程退出码 1:“instance already running (lock held)” |
|
||||
| 优雅退出 | SIGTERM 后进程退出(drain 逻辑 T20-B7 已在库;本次日志因清理时序未留存,退出行为符合预期) |
|
||||
|
||||
隔离纪律:一次性 PG 容器(5544 端口)用后即删,未触碰真实 dev/test 数据;
|
||||
冒烟目录与二进制已清理。
|
||||
|
||||
## U10 基建汇合状态
|
||||
|
||||
U10a(迁移/提示词/xlsx 内嵌 + config check)、U10b(五层配置栈 + 字段溯源)、
|
||||
U10c(实例身份/单启锁/根校验 + systemd 模板)全部就位并被本冒烟整体消费。
|
||||
优雅退出/readiness 经核实**既有实现已达标**(drain 窗口对齐 AgentTimeout、
|
||||
分量就绪健康端点、先初始化后监听——端口打开即就绪,无需冗余改造)。
|
||||
|
||||
## 未完成 / 后续
|
||||
|
||||
- **RC 未发布**:按用户指令组件仓/发布仓暂不关联 Gitea;二进制仅本地验证。
|
||||
发布需建 Agent-System-Releases-Internal(private)并经授权。
|
||||
- 完整 V9/V27 验收(业务任务、上传/检索、升级/回退、重复发布冲突)待
|
||||
发布阶段在更完整环境执行。
|
||||
- managed-local PG profile、serve/init 子命令分化(KTD16)后续补充。
|
||||
- 版本号方案:本次为无 tag 冒烟构建;正式 RC 走 `vX.Y.Z-rc.N` 命名。
|
||||
+125
-9
@@ -1,6 +1,6 @@
|
||||
# 当前焦点
|
||||
|
||||
**更新**:2026-09-23(DOCREV UI PASS + FEATURE-MATRIX A–G done / 红线证据入账)。此文件是协调快照;实际分支、进程、执行租约以机器核验为准。能力和发布结论分别见 [FEATURE-MATRIX](../status/FEATURE-MATRIX.md) / [gap-matrix](../remediation/gap-matrix.md)。
|
||||
**更新**:2026-09-23(剩余 worktree 收口:go-agentx+FAV 合入 local_dev;注册 worktree 已清;FAV live 仍不放量)。此文件是协调快照;实际分支、进程、执行租约以机器核验为准。能力和发布结论分别见 [FEATURE-MATRIX](../status/FEATURE-MATRIX.md) / [gap-matrix](../remediation/gap-matrix.md)。
|
||||
|
||||
本机 macOS 已可用 `agentctl with`/`docs apply`/`validate`/`integrate`(W1-B 进程层);共享文档写走 docs apply 收据。
|
||||
|
||||
@@ -12,13 +12,111 @@
|
||||
|
||||
2. **dev→test 已晋升**:`origin/dev@591ea601`(schema 61 门禁绿);`origin/test@83c6a12a` + tag `rc-v1.1.0-beta.1`;test 环境 health schema=61、Runner `MiniMax-M3`。[报告](../test-reports/2026-09-22-dev-gate-and-test-promotion-test-report.md)。
|
||||
3. **本任务 cleanup=pending**:feature / integrate / promote-test worktrees 待独立维护者按门禁复查后清理;不强删。
|
||||
4. **Agent 规范与 L1 门禁**:R01–R10、共享 .locks 已启用;本机 macOS 上租约路径不可用,受测 Linux 主机仍 enforced。
|
||||
4. **Agent 规范与 L1 门禁**:R01–R10、共享 .locks 已启用;本机 macOS 租约路径可用(Darwin 进程层已落地),与 Linux 双平台 enforced。
|
||||
|
||||
## 并行认领
|
||||
|
||||
| owner | task | branch | worktree | mutex | status |
|
||||
|---|---|---|---|---|---|
|
||||
| Cursor | agent-governance-config-2026-09-23 | feature/agent-governance-config-2026-09-23 | .worktrees/agent-governance-config-2026-09-23 | agent-governance-config | in_progress |
|
||||
| Cursor | controlled-projection-project-binding-2026-09-28 | fix/controlled-projection-project-binding-2026-09-28 | .worktrees/controlled-projection-project-binding-2026-09-28 | controlled-projection-binding | done |
|
||||
| Cursor | docgov-shared-map-race-2026-09-28-r2 | fix/docgov-shared-map-race-2026-09-28 | .worktrees/docgov-shared-map-race-2026-09-28 | docgov-shared-map-race | done |
|
||||
| Cursor | promote-rc-beta6-closeout-2026-09-28 | feature/promote-rc-beta6-closeout-2026-09-28 | .worktrees/promote-rc-beta6-closeout-2026-09-28 | git:test+env:test | done |
|
||||
| Cursor | quality-gate-heading-deploy-2026-09-28 | fix/quality-gate-heading-mismatch-2026-09-28 | .worktrees/quality-gate-heading-mismatch-2026-09-28 | quality-gate-heading | done |
|
||||
| Cursor | quality-gate-heading-mismatch-2026-09-28-r3 | fix/quality-gate-heading-mismatch-2026-09-28 | .worktrees/quality-gate-heading-mismatch-2026-09-28 | quality-gate-heading | done |
|
||||
| Cursor | nightly-advance-automation-2026-09-28 | feature/nightly-advance-automation-2026-09-28 | .worktrees/nightly-advance-automation-2026-09-28 | nightly-advance | done || Cursor | agent-reply-llm-narrative-2026-09-28 | feature/agent-reply-llm-narrative-2026-09-28 | .worktrees/agent-reply-llm-narrative-2026-09-28 | chat+coordinator | in_progress |
|
||||
| Cursor | test-user-doc-issues-2026-09-28 | fix/test-user-doc-issues-2026-09-28 | .worktrees/test-user-doc-issues-2026-09-28 | intent-write-verb | done |
|
||||
| Cursor | pi-runner-env-mismatch-2026-09-28 | fix/pi-runner-env-mismatch-2026-09-28 | .worktrees/pi-runner-env-mismatch-2026-09-28 | pi-runner-env | done |
|
||||
| Cursor | error-events-pg-roundtrip-2026-09-28 | feature/error-events-pg-roundtrip-2026-09-28 | .worktrees/error-events-pg-roundtrip-2026-09-28 | error-events-pg-evidence | done |
|
||||
| Cursor | error-code-observability-2026-09-28 | feature/error-code-observability-2026-09-28 | .worktrees/error-code-observability-2026-09-28 | error-code-observability | done |
|
||||
| Cursor | attachment-only-turn-2026-09-28 | fix/attachment-only-turn-2026-09-28 | .worktrees/attachment-only-turn-2026-09-28 | attachment-only-turn | done |
|
||||
| Cursor | activation-preview-precheck-2026-09-28 | fix/activation-preview-400-precheck-2026-09-28 | .worktrees/activation-preview-400-precheck-2026-09-28 | web-activation-preview | done |
|
||||
| Cursor | squad-commit-authority-2026-09-28 | fix/squad-commit-authority-2026-09-28 | .worktrees/squad-commit-authority-2026-09-28 | bizdev+docflow | in_progress |
|
||||
| Cursor | auth-register-internal-2026-09-28 | fix/auth-register-internal-2026-09-28 | .worktrees/auth-register-internal-2026-09-28 | auth-register | done |
|
||||
| Cursor | restore-admin-password-reset-2026-09-28 | feature/restore-admin-password-reset-2026-09-28 | .worktrees/restore-admin-password-reset-2026-09-28 | auth | done |
|
||||
| pi | test-single-binary-2026-09-27 | feature/test-single-binary-2026-09-27 | .worktrees/test-single-binary-2026-09-27 | env:dev+env:test+git:dev+git:test | done |
|
||||
| pi | upload-doc-access-2026-09-27 | fix/upload-doc-access-2026-09-27 | .worktrees/upload-doc-access-2026-09-27 | freedoc+web-upload | done |
|
||||
| pi | frontend-demo-fallback-2026-09-27-r3c | fix/frontend-demo-fallback-2026-09-27-r3 | (已清理) | web-chat-fallback | done |
|
||||
| pi | frontend-demo-fallback-2026-09-27-r2 | fix/frontend-demo-fallback-2026-09-27 | (已清理) | web-chat-fallback | done |
|
||||
| Cursor | full-system-browser-e2e-2026-09-26 | feature/full-system-browser-e2e-2026-09-26 | .worktrees/full-system-browser-e2e-2026-09-26 | env:dev+docs-test-report | done |
|
||||
| pi | sysadmin-maturity-refresh-2026-09-26 | feature/sysadmin-maturity-refresh-2026-09-26 | .worktrees/sysadmin-maturity-refresh-2026-09-26 | sysadmin-maturity | done |
|
||||
| pi | degraded-flags-enable-2026-09-26-r4 | feature/degraded-flags-enable-2026-09-26 | .worktrees/degraded-flags-enable-2026-09-26 | summary-flags-rollout | done |
|
||||
| pi | system-review-p0-p1-fixes-2026-09-26 | fix/system-review-p0-p1-fixes-2026-09-26 | .worktrees/system-review-p0-p1-fixes-2026-09-26 | review-fixes-batch | done |
|
||||
| Cursor | system-code-review-2026-09-26 | feature/system-code-review-2026-09-26 | .worktrees/system-code-review-2026-09-26 | docs-audit-review | done |
|
||||
| pi | swboot-closeout-2026-09-26-r3 | feature/swboot-closeout-2026-09-26 | .worktrees/swboot-closeout-2026-09-26 | workflow-design | done |
|
||||
| pi | swboot-closeout-2026-09-26-r2 | feature/swboot-closeout-2026-09-26 | .worktrees/swboot-closeout-2026-09-26 | workflow-design | in_progress |
|
||||
| pi | chat-semantic-replace-2026-09-26 | feature/chat-semantic-replace-2026-09-26 | .worktrees/chat-semantic-replace-2026-09-26 | chat | done |
|
||||
| pi | jevdecide-soak-2026-09-26 | feature/jevdecide-soak-2026-09-26 | .worktrees/jevdecide-soak-2026-09-26 | jevdecide | done |
|
||||
| pi | dialogue-ctx-closeout-2026-09-26-r4 | feature/dialogue-ctx-closeout-2026-09-26 | .worktrees/dialogue-ctx-closeout-2026-09-26 | dialogue-ctx | done |
|
||||
| pi | dialogue-ctx-closeout-2026-09-26-r2 | feature/dialogue-ctx-closeout-2026-09-26 | .worktrees/dialogue-ctx-closeout-2026-09-26 | dialogue-ctx | in_progress |
|
||||
| pi | worktree-final-closeout-2026-09-26 | feature/worktree-final-closeout-2026-09-26 | (已清理) | git:dev+docs | done |
|
||||
| cursor-auto | cleanup-audit-r3-2026-09-25 | feature/cleanup-audit-p11-2026-09-25 | .worktrees/cleanup-audit-p11-2026-09-25 | docs-cleanup-audit | done |
|
||||
| Cursor | admin-settings-maint-b-2026-09-25 | feature/admin-env-settings-maintenance-2026-09-25 | .worktrees/admin-env-settings-maintenance-2026-09-25 | admin-settings-maintenance | done |
|
||||
| Cursor | dm-migration-2026-09-24-r2 | feature/dm-migration-2026-09-24 | .worktrees/dm-migration-2026-09-24 | dm-migration | done |
|
||||
| Cursor | governance-console-p1-impl-2026-09-24 | feature/governance-console-p1-impl-2026-09-24 | .worktrees/governance-console-p1-impl-2026-09-24 | agentctl-console | done |
|
||||
| Cursor | governance-console-p1-design-2026-09-24 | feature/governance-console-p1-design-2026-09-24 | .worktrees/governance-console-p1-design-2026-09-24 | agentctl-console-design | done |
|
||||
| Cursor | governance-visibility-p0-2026-09-24 | feature/governance-visibility-p0-2026-09-24 | .worktrees/governance-visibility-p0-2026-09-24 | agentctl-visibility | done |
|
||||
| Cursor | worktree-cleanup-closeout-2026-09-24 | feature/worktree-cleanup-closeout-2026-09-24 | (已清理) | worktree-cleanup | done |
|
||||
| Cursor | non-author-closeout-2026-09-24 | feature/non-author-closeout-2026-09-24 | .worktrees/non-author-closeout-2026-09-24 | docs+git:dev | done |
|
||||
| Cursor | integrate-non-author-docs-2026-09-24 | feature/integrate-non-author-docs-2026-09-24 | .worktrees/integrate-non-author-docs-2026-09-24 | git:dev | done |
|
||||
| Cursor | non-author-member-access-docs-2026-09-24 | feature/non-author-member-access-2026-09-24 | .worktrees/non-author-member-access-2026-09-24 | docs+matrix | done |
|
||||
| Cursor | non-author-member-access-2026-09-24 | feature/non-author-member-access-2026-09-24 | .worktrees/non-author-member-access-2026-09-24 | docgov+iam-authz+workflow-gov | done |
|
||||
| Cursor | integrate-free-collab-2026-09-24 | feature/integrate-free-collab-2026-09-24 | .worktrees/integrate-free-collab-2026-09-24 | integrate-dev | done |
|
||||
| Cursor | cursor-governance-hooks-2026-09-24 | feature/cursor-governance-hooks-2026-09-24 | .worktrees/cursor-governance-hooks-2026-09-24 | cursor-governance | done |
|
||||
| Cursor | governance-catalog-2026-09-24 | feature/governance-catalog-2026-09-24 | .worktrees/governance-catalog-2026-09-24 | agent-workflow-governance+catalog | done |
|
||||
| Codex | subagent-workflow-standard-2026-09-24-land | feature/subagent-workflow-standard-2026-09-24 | .worktrees/subagent-workflow-standard-2026-09-24 | pi-subagent-integration | done |
|
||||
| Cursor/Codex | subagent-workflow-standard-2026-09-24-executor | feature/subagent-workflow-standard-2026-09-24 | .worktrees/subagent-workflow-standard-2026-09-24 | pi-subagent-executor | done |
|
||||
| Codex | subagent-workflow-standard-2026-09-24-config-r2 | feature/subagent-workflow-standard-2026-09-24 | .worktrees/subagent-workflow-standard-2026-09-24 | subagent-workflow-docs | done |
|
||||
| Codex | subagent-workflow-standard-2026-09-24 | feature/subagent-workflow-standard-2026-09-24 | .worktrees/subagent-workflow-standard-2026-09-24 | subagent-workflow-docs | done |
|
||||
| Cursor | integrate-gate-nightly-fixes-b-2026-09-24 | feature/integrate-gate-nightly-fixes-b-2026-09-24 | .worktrees/integrate-gate-nightly-fixes-b-2026-09-24 | git:dev | done |
|
||||
| Cursor | integrate-gate-nightly-fixes-2026-09-24 | feature/integrate-gate-nightly-fixes-2026-09-24 | .worktrees/integrate-gate-nightly-fixes-2026-09-24 | git:dev | done |
|
||||
| Cursor | integrate-docs-gate-promo-report-2026-09-24 | feature/integrate-docs-gate-promo-report-2026-09-24 | .worktrees/integrate-docs-gate-promo-report-2026-09-24 | git:dev | done |
|
||||
| Cursor | promote-rc-beta3-c-2026-09-24 | feature/promote-rc-beta3-c-2026-09-24 | .worktrees/promote-rc-beta3-c-2026-09-24 | git:test+env:test+docs | done |
|
||||
| Cursor | dev-full-gate-test-promo-2026-09-24 | feature/dev-full-gate-test-promo-2026-09-24 | .worktrees/dev-full-gate-test-promo-2026-09-24 | git:dev+env:dev+env:test+docs | done |
|
||||
| Cursor | gate-promo-current-close-2026-09-24 | feature/gate-promo-current-close-2026-09-24 | .worktrees/gate-promo-current-close-2026-09-24 | docs:admin+docs | done |
|
||||
| Cursor | docs-gate-promo-report-2026-09-24 | feature/docs-gate-promo-report-2026-09-24 | .worktrees/docs-gate-promo-report-2026-09-24 | docs+git:dev | done |
|
||||
| Cursor | admin-password-reset-2026-09-24 | feature/admin-password-reset-2026-09-24 | .worktrees/admin-password-reset-2026-09-24 | auth+env:test | done |
|
||||
| Cursor | fix-fav-staging-uuid-2026-09-24 | fix/fix-fav-staging-uuid-2026-09-24 | .worktrees/fix-fav-staging-uuid-2026-09-24 | artifactvault | done |
|
||||
| Cursor | gate-e1a-unique-project-name-2026-09-24 | fix/gate-e1a-unique-project-name-2026-09-24 | .worktrees/gate-e1a-unique-project-name-2026-09-24 | docnotify | done |
|
||||
| Cursor | gate-unhook-docquery-2026-09-24 | fix/gate-unhook-docquery-2026-09-24 | .worktrees/gate-unhook-docquery-2026-09-24 | server+docquery | done |
|
||||
| Cursor | integrate-jev-assist-land-2026-09-24 | feature/integrate-jev-assist-land-2026-09-24 | .worktrees/integrate-jev-assist-land-2026-09-24 | git:dev | done |
|
||||
| Cursor | integrate-codegraph-fixup2-2026-09-24 | feature/integrate-codegraph-fixup2-2026-09-24 | (removed) | git:dev | done |
|
||||
| Cursor | integrate-codegraph-governance-2026-09-24 | feature/integrate-codegraph-governance-2026-09-24 | (removed) | git:dev | done |
|
||||
| Cursor | codegraph-governance-r2-2026-09-24 | feature/codegraph-governance-2026-09-24 | .worktrees/codegraph-governance-2026-09-24 | agent-workflow-governance+codegraph | done |
|
||||
| Cursor | jev-dev-shadow-on-2026-09-24 | feature/jev-dev-shadow-on-2026-09-24 | .worktrees/jev-dev-shadow-on-2026-09-24 | env:dev+jevdecide | done |
|
||||
| Cursor | jev-product-closeout-2026-09-24 | feature/jev-product-closeout-2026-09-24 | .worktrees/jev-product-closeout-2026-09-24 | jevdecide+coordinator | done |
|
||||
| Cursor | jev-product-shadow-2026-09-24 | feature/jev-product-shadow-2026-09-24 | .worktrees/jev-product-shadow-2026-09-24 | jevdecide+coordinator | done |
|
||||
| Cursor | jev-mcp-docs-done-2026-09-24 | feature/jev-mcp-docs-done-2026-09-24 | .worktrees/jev-mcp-docs-done-2026-09-24 | jev-mcp+docs | done |
|
||||
| Cursor | jev-mcp-integration-2026-09-24 | feature/jev-mcp-integration-2026-09-24 | .worktrees/jev-mcp-integration-2026-09-24 | jev-mcp+docs | done |
|
||||
| Cursor | integrate-intent-plan-u9u12-land-2026-09-24 | feature/integrate-intent-plan-u9u12-land-2026-09-24 | .worktrees/integrate-intent-plan-u9u12-land-2026-09-24 | git:dev | done |
|
||||
| Cursor | integrate-pi-narrative-docs-2026-09-23 | feature/integrate-pi-narrative-docs-2026-09-23 | .worktrees/integrate-pi-narrative-final-closeout-b-2026-09-23 | git:dev | done |
|
||||
| Cursor | pi-narrative-final-closeout-b-2026-09-23 | feature/pi-narrative-final-closeout-b-2026-09-23 | .worktrees/pi-narrative-final-closeout-2026-09-23 | docgov | done |
|
||||
| Cursor | chat-semantic-d3-matrix-land-2026-09-23 | feature/chat-semantic-d3-matrix-land-2026-09-23 | .worktrees/chat-semantic-d3-matrix-land-2026-09-23 | chat | done |
|
||||
| Cursor | intent-plan-i2-rollout-b-2026-09-24 | feature/intent-plan-i2-rollout-2026-09-24 | (已清理) | intent-plan | done |
|
||||
| Cursor | intent-plan-i2-impl-2026-09-24 | feature/intent-plan-i2-shadow-allowlist-2026-09-24 | (已清理) | intent-plan | done |
|
||||
| Cursor | closeout-claim-removed-2026-09-23 | feature/closeout-claim-removed-2026-09-23 | (removed) | git:dev+worktree-cleanup | done |
|
||||
| Cursor | module-batches-ag-status-fix-2026-09-23 | feature/module-batches-ag-status-fix-2026-09-23 | .worktrees/module-batches-ag-status-fix-2026-09-23 | module-decoupling-spec | done |
|
||||
| Cursor | fav-constraint-current-2026-09-23 | feature/fav-constraint-current-2026-09-23 | (removed) | git:dev+docs | done |
|
||||
| Cursor | closeout-worktree-cleanup-2026-09-23 | feature/closeout-worktree-cleanup-2026-09-23 | .worktrees/closeout-worktree-cleanup-2026-09-23 | git:dev+worktree-cleanup | done |
|
||||
| Cursor | remaining-worktrees-closeout-2026-09-23 | feature/remaining-worktrees-closeout-2026-09-23 | (removed) | git:dev+worktree-cleanup | done |
|
||||
| Cursor | worktree-closeout-cleanup-2026-09-23 | feature/worktree-closeout-cleanup-2026-09-23 | .worktrees/worktree-closeout-cleanup-2026-09-23 | git:dev+worktree-cleanup | done |
|
||||
| Cursor | worktree-closeout-batch-2026-09-23 | feature/worktree-closeout-batch-2026-09-23 | (removed) | git:dev+worktree-cleanup | done |
|
||||
| Cursor | agentctl-cursor-integration-close-2026-09-23 | feature/agentctl-cursor-integration-close-2026-09-23 | .worktrees/agentctl-cursor-integration-close-2026-09-23 | agentctl-cursor-integration-close | done |
|
||||
| Cursor | integrate-agentctl-cursor-integration-2026-09-23 | feature/integrate-agentctl-cursor-integration-2026-09-23 | .worktrees/integrate-agentctl-cursor-integration-2026-09-23 | git:dev | done |
|
||||
| Cursor | agentctl-cursor-integration-2026-09-23 | feature/agentctl-cursor-integration-2026-09-23 | .worktrees/agentctl-cursor-integration-2026-09-23 | agentctl-cursor-integration | done |
|
||||
| Cursor | agentctl-mgmt-go-live-close-2026-09-23 | feature/agentctl-mgmt-go-live-close-2026-09-23 | .worktrees/agentctl-mgmt-go-live-close-2026-09-23 | agentctl-mgmt-go-live-close | done |
|
||||
| Cursor | integrate-agentctl-mgmt-go-live-2026-09-23 | feature/integrate-agentctl-mgmt-go-live-2026-09-23 | .worktrees/integrate-agentctl-mgmt-go-live-2026-09-23 | git:dev | done |
|
||||
| Cursor | agentctl-mgmt-go-live-2026-09-23 | feature/agentctl-mgmt-go-live-2026-09-23 | .worktrees/agentctl-mgmt-go-live-2026-09-23 | agentctl-mgmt-go-live | done |
|
||||
| Cursor | w3-u6-current-fix-2026-09-23 | feature/w3-u6-current-fix-2026-09-23 | .worktrees/w3-u6-current-fix-2026-09-23 | w3-u6-current-fix | done |
|
||||
| Cursor | integrate-w3-u6-closeout-2026-09-23 | feature/integrate-w3-u6-closeout-2026-09-23 | .worktrees/integrate-w3-u6-closeout-2026-09-23 | git:dev | done |
|
||||
| Cursor | integrate-matrix-record-id-2026-09-23 | feature/integrate-matrix-record-id-2026-09-23 | .worktrees/integrate-matrix-record-id-2026-09-23 | git:dev | done |
|
||||
| Cursor | w3-u6-closeout-2026-09-23 | feature/w3-u6-closeout-2026-09-23 | .worktrees/w3-u6-closeout-2026-09-23 | w3-u6-closeout | done |
|
||||
| Cursor | matrix-record-id-2026-09-23 | feature/matrix-record-id-2026-09-23 | .worktrees/matrix-record-id-2026-09-23 | matrix-record-id | done |
|
||||
| Cursor | w2-closeout-2026-09-23 | feature/w2-closeout-2026-09-23 | .worktrees/w2-closeout-2026-09-23 | w2-closeout | done |
|
||||
| Cursor | current-projection-2026-09-23 | feature/current-projection-2026-09-23 | .worktrees/current-projection-2026-09-23 | current-projection | done |
|
||||
| Cursor | agentctl-daemon-2026-09-23 | feature/agentctl-daemon-2026-09-23 | .worktrees/agentctl-daemon-2026-09-23 | agentctl-daemon | done |
|
||||
| Cursor | agentctl-handoff-2026-09-23 | feature/agentctl-handoff-2026-09-23 | .worktrees/agentctl-handoff-2026-09-23 | agentctl-handoff | done |
|
||||
| Cursor | agentctl-claim-2026-09-23 | feature/agentctl-claim-2026-09-23 | .worktrees/agentctl-claim-2026-09-23 | agentctl-claim | done |
|
||||
| Cursor | agent-governance-config-2026-09-23 | feature/agent-governance-config-2026-09-23 | .worktrees/agent-governance-config-2026-09-23 | agent-governance-config | done |
|
||||
| Cursor | coordination-db-daemon-impl-plan-2026-09-23 | feature/coordination-db-daemon-impl-plan-2026-09-23 | .worktrees/coordination-db-daemon-impl-plan-2026-09-23 | coordination-db-daemon-impl-plan | done |
|
||||
| Cursor | coordination-db-daemon-2026-09-23 | feature/coordination-db-daemon-2026-09-23 | .worktrees/coordination-db-daemon-2026-09-23 | coordination-db-daemon | done |
|
||||
| Cursor | integrate-pi-runner-response-size-r2-2026-09-23 | feature/integrate-pi-runner-response-size-2026-09-23 | .worktrees/integrate-pi-runner-response-size-2026-09-23 | git:dev | done |
|
||||
@@ -30,29 +128,47 @@
|
||||
| Cursor | integrate-dev-prod-ready-test-promotion-2026-09-22 | feature/integrate-dev-prod-ready-test-promotion-2026-09-22 | .worktrees/integrate-dev-prod-ready-test-promotion-2026-09-22 | git:dev | done |
|
||||
| Cursor | promote-test-2026-09-22 | feature/promote-test-2026-09-22 | .worktrees/promote-test-2026-09-22 | git:test | done |
|
||||
| Codex | 2026-09-21-agent-workflow-governance-adoption | feature/agent-workflow-governance-plan | (本机 clone 后不存在) | agent-workflow-governance | done |
|
||||
| Codex | issue-learning-2026-09-23 | feature/issue-learning-2026-09-23 | .worktrees/issue-learning-2026-09-23 | issue-learning-docs | done |
|
||||
| Codex | systemic-issue-analysis-2026-09-23 | feature/systemic-issue-analysis-2026-09-23 | .worktrees/systemic-issue-analysis-2026-09-23 | systemic-issue-analysis-docs | done |
|
||||
| Codex | modular-contract-standard-2026-09-22 | feature/modular-contract-standard-2026-09-22 | .worktrees/modular-contract-standard-2026-09-22 | modular-contract-docs | done |
|
||||
| Codex | herdr-orchestration-v12 | feature/herdr-orchestration-v12 | .worktrees/herdr-orchestration-v12 | herdr-policy+scripts | done |
|
||||
| Codex | 2026-09-21-agent-governance-implementation | feature/agent-governance-implementation | .worktrees/agent-governance-implementation | agent-governance | done |
|
||||
| Cursor | 2026-09-21-force-material-chunk-index | feature/force-material-chunk-index-2026-09-21 | .worktrees/force-material-chunk-index-2026-09-21 | bizdev+materialindex | done |
|
||||
| Cursor | 2026-09-21-workflow-scope-weighting | feature/workflow-scope-weighting-2026-09-21 | .worktrees/workflow-scope-weighting-2026-09-21 | intent+web+docgov | done |
|
||||
| Cursor | 2026-09-21-upload-parse-ux-dedup | feature/upload-parse-ux-2026-09-21 | .worktrees/upload-parse-ux-2026-09-21 | server+web+storage | done |
|
||||
| Cursor | 2026-09-21-mineru-doc-parsing | feature/mineru-doc-parsing-2026-09-21 | .worktrees/mineru-doc-parsing-2026-09-21 | storage+bizdev+kb | done |
|
||||
| Cursor | 2026-09-21-intent-confirm-stage-aware | fix/intent-confirm-stage-aware-2026-09-21 | .worktrees/intent-confirm-stage-aware-2026-09-21 | intent+web+docgov | done |
|
||||
| Cursor | 2026-09-21-taskrun-status-card | feature/taskrun-status-card-2026-09-21 | .worktrees/feature-taskrun-status-card-2026-09-21 | chat+web+taskrun | done |
|
||||
| Codex | 2026-09-21-agent-workflow-governance-plan | feature/agent-workflow-governance-plan | .worktrees/feature-agent-workflow-governance-plan | agent-workflow-governance-plan | done |
|
||||
| Cursor | 2026-09-21-workflow-doc-key-unification | fix/workflow-doc-key-unification-2026-09-21 | .worktrees/fix-workflow-doc-key-unification-2026-09-21 | docgov+web | done |
|
||||
| Cursor | 2026-09-21-dev-multiuser-four-issues | fix/dev-multiuser-four-issues-2026-09-21 | .worktrees/fix-dev-multiuser-four-issues | projectinstance+docgov | done |
|
||||
| Codex | 2026-09-17-initial-load-performance-plan | feature/initial-load-performance-plan | .worktrees/feature-initial-load-performance-plan | loading-performance-audit | done |
|
||||
| Cline | 2026-09-16-partial-deferred-completion | docs/partial-deferred-completion-plan | - | architecture-docs | in_progress |
|
||||
| Cursor | dialogue-context-injection-2026-09-25 | feature/dialogue-context-injection-2026-09-25 | (已清理) | dialogue-ctx | done |
|
||||
| Cursor | dialogue-context-injection-2026-09-25-r2 | feature/dialogue-context-injection-2026-09-25 | .worktrees/dialogue-context-injection-2026-09-25 | dialogue-ctx | done |
|
||||
|
||||
## 清理接管与遗留现场
|
||||
|
||||
| 路径/事项 | 分类与保留原因 | cleanup_owner | 复查触发 |
|
||||
|---|---|---|---|
|
||||
| `.worktrees/docrev-ui-rerun-2026-09-22` / `freeform-project-id-bigint` | 任务 done;UI PASS 密封;cleanup=pending | 独立维护者 | tip 为 local_dev 祖先且无 Playwright 后 remove |
|
||||
| `.worktrees/dev-prod-ready-test-promotion-2026-09-22` 等本轮三个 worktree | 任务 done;cleanup=pending;证据已入 test-reports / gap-matrix | 独立维护者 | 核对 tip 为 origin/dev 或 origin/test 祖先、无进程后 remove |
|
||||
| `.worktrees/docrev-ui-rerun-2026-09-22` / `freeform-project-id-bigint` | 已清理 / 目录不存在(2026-09-23 核对) | Cursor | 无 |
|
||||
| `.worktrees/dev-prod-ready-test-promotion-2026-09-22` 等本轮三个 worktree | 已清理 / 目录不存在(2026-09-23 核对) | Cursor | 无 |
|
||||
| Cline `2026-09-16-partial-deferred-completion` | 仍 in_progress;W5–W7 未关闭 | Cline owner / 维护者 | 单独授权实施或交接 |
|
||||
| 保护分支 / FAV 相关 | 保护项;故意不合入、不删 | 原 owner / 维护者 | 用户调整保护边界后 |
|
||||
| 保护分支 / FAV 相关 | 已合入 local_dev(例外授权 2026-09-23);live 未放量;分支/worktree 已删 | Cursor | 无;见 integrate-fav-final 例外登记 |
|
||||
| embedding 401(dmxapi) | 非 blocker 运维债;不挡 PI | 运维 | 换钥后重跑 chunk index |
|
||||
|
||||
## 集成槽位
|
||||
|
||||
| holder | phase | since | scope | queue |
|
||||
|--------|-------|-------|-------|-------|
|
||||
| - | idle | 2026-09-22 | 本轮合入与 test 晋升已完成并推送;后续合入须重新认领串行 | - |
|
||||
| - | idle | 2026-09-21 | force-material-chunk-index 已合入 dev 并从主目录 rebuild;项目 6579 候选 535 已确认;schema=61 | - |
|
||||
|
||||
**phase**: `idle` | `merging` | `smoke` | `e2e`
|
||||
|
||||
> 合入 `dev` + 共享容器验证必须串行。实际机器锁/进程优先;详见 [操作规范](./2026-09-21-agent-worktree-workflow.md)。
|
||||
|
||||
## 受控约束
|
||||
|
||||
- 禁止整支 merge FAV;保留既有保护分支;不删 `origin/*`(本轮仅前进 `dev`/`test` 与新增 rc tag)。
|
||||
- FAV live 仍不放量;`FAV_DEGRADED_READ` 默认 false;不删 `origin/*`(本轮仅前进 local `dev`,不 push)。
|
||||
- 不默认升 `MULTI_INTENT_PLAN_TIER=full`;`SEED_DEMO_USERS=false` 在 test 保持。
|
||||
- D7 对话 ADR 仍待合规签字;追踪表类别 `record` 不授权物理删除。
|
||||
- main 未在本轮晋升。
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
OK status -> allow
|
||||
OK push -> ask
|
||||
OK reset -> ask
|
||||
OK clean -> ask
|
||||
OK force-wt -> ask
|
||||
hooks OK
|
||||
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"initialize": {
|
||||
"name": "agentctl",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"tools": [
|
||||
"status",
|
||||
"task_register",
|
||||
"task_close",
|
||||
"lease_run",
|
||||
"docs_snapshot",
|
||||
"docs_apply",
|
||||
"validate",
|
||||
"queue_enqueue",
|
||||
"quarantine_status"
|
||||
],
|
||||
"status_ok": true,
|
||||
"daemon_ok": true,
|
||||
"daemon_held": true
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
queue retry after parking untracked promotion receipts (DIRTY_TREE) at /tmp/ci-hold-receipts
|
||||
@@ -0,0 +1,5 @@
|
||||
OK agentctl-session-start lines 30
|
||||
OK agentctl-worktree-setup lines 48
|
||||
OK agentctl-lease-write lines 45
|
||||
OK agentctl-integrate-closeout lines 53
|
||||
skills OK
|
||||
@@ -0,0 +1,2 @@
|
||||
146:Ran 134 tests in 122.988s
|
||||
148:OK (skipped=3)
|
||||
@@ -0,0 +1 @@
|
||||
bootstrap: ok
|
||||
@@ -0,0 +1,5 @@
|
||||
{"interval": 1.0, "max_cycles": 3, "pid": 63316, "status": "daemon_started"}
|
||||
{"processed": 0, "results": [], "status": "ok"}
|
||||
{"processed": 0, "results": [], "status": "ok"}
|
||||
{"processed": 0, "results": [], "status": "ok"}
|
||||
{"cycles": 3, "pid": 63316, "reason": "max_cycles", "status": "daemon_stopped"}
|
||||
@@ -0,0 +1 @@
|
||||
{"epoch": "7fa35ad9-518f-4a0d-a446-49baf12c666c", "heartbeat": {"cycle": 99, "pid": 63557, "updated": 1790158027.962433}, "heartbeat_age_seconds": 0.2736787796020508, "lock_root": "/private/tmp/Agent-System/.locks", "manager_lock": {"held": true, "holder_pid": 63557, "path": "/private/tmp/Agent-System/.locks/os/manager.lock"}, "queue": {"claimed": 0, "pending": 0}, "status": "ok"}
|
||||
@@ -0,0 +1 @@
|
||||
{"epoch": "7fa35ad9-518f-4a0d-a446-49baf12c666c", "heartbeat": {"cycle": 2, "pid": 63557, "updated": 1790157919.612233}, "heartbeat_age_seconds": 0.8667151927947998, "lock_root": "/private/tmp/Agent-System/.locks", "manager_lock": {"held": true, "holder_pid": 63557, "path": "/private/tmp/Agent-System/.locks/os/manager.lock"}, "queue": {"claimed": 0, "pending": 0}, "status": "ok"}
|
||||
@@ -0,0 +1 @@
|
||||
f1b4fdca-0209-466d-9aba-fcd8f90bb3be completed; tip 5e11db50
|
||||
@@ -0,0 +1 @@
|
||||
Darwin WeiCHENdeMac-mini.local 25.6.0 Darwin Kernel Version 25.6.0: Fri Jul 31 19:17:26 PDT 2026; root:xnu-12377.161.14~5/RELEASE_ARM64_T6041 arm64
|
||||
@@ -0,0 +1,6 @@
|
||||
5: state = running
|
||||
38: runs = 1
|
||||
39: pid = 63557
|
||||
50: last exit code = (never exited)
|
||||
55: state = active
|
||||
63: state = active
|
||||
@@ -0,0 +1,13 @@
|
||||
2: active count = 1
|
||||
3: path = /Users/weichen/Library/LaunchAgents/com.agentctl.coordinator.plist
|
||||
5: state = running
|
||||
7: program = /usr/bin/python3
|
||||
17: working directory = /private/tmp/Agent-System
|
||||
19: stdout path = /tmp/agentctl-coordinator.out.log
|
||||
20: stderr path = /tmp/agentctl-coordinator.err.log
|
||||
38: runs = 1
|
||||
39: pid = 63557
|
||||
55: state = active
|
||||
56: active count = 1
|
||||
63: state = active
|
||||
64: active count = 1
|
||||
@@ -0,0 +1,3 @@
|
||||
domain=gui/501
|
||||
dest=/Users/weichen/Library/LaunchAgents/com.agentctl.coordinator.plist
|
||||
cmd: launchctl bootstrap gui/501 /Users/weichen/Library/LaunchAgents/com.agentctl.coordinator.plist
|
||||
@@ -0,0 +1,27 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>KeepAlive</key>
|
||||
<true/>
|
||||
<key>Label</key>
|
||||
<string>com.agentctl.coordinator</string>
|
||||
<key>ProgramArguments</key>
|
||||
<array>
|
||||
<string>/usr/bin/python3</string>
|
||||
<string>/private/tmp/Agent-System/scripts/agentctl.py</string>
|
||||
<string>daemon</string>
|
||||
<string>run</string>
|
||||
<string>--interval</string>
|
||||
<string>1.0</string>
|
||||
</array>
|
||||
<key>RunAtLoad</key>
|
||||
<true/>
|
||||
<key>StandardErrorPath</key>
|
||||
<string>/tmp/agentctl-coordinator.err.log</string>
|
||||
<key>StandardOutPath</key>
|
||||
<string>/tmp/agentctl-coordinator.out.log</string>
|
||||
<key>WorkingDirectory</key>
|
||||
<string>/private/tmp/Agent-System</string>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -0,0 +1 @@
|
||||
2026-09-23T10:05:09Z
|
||||
@@ -0,0 +1,3 @@
|
||||
1:{"interval": 1.0, "max_cycles": null, "pid": 63557, "status": "daemon_started"}
|
||||
126:{"run_id": "queue-f1b4fdca-0209-466d-9aba-fcd8f90bb3be", "sha": "5e11db50ce6f8905890993cef1d4a64bbb6f53d9", "status": "merged"}
|
||||
127:{"processed": 1, "results": [{"id": "f1b4fdca-0209-466d-9aba-fcd8f90bb3be", "run_id": "queue-f1b4fdca-0209-466d-9aba-fcd8f90bb3be", "status": "completed"}], "status": "ok"}
|
||||
@@ -0,0 +1 @@
|
||||
weichen
|
||||
@@ -0,0 +1 @@
|
||||
/Users/weichen/Library/LaunchAgents/com.agentctl.coordinator.plist: OK
|
||||
@@ -0,0 +1 @@
|
||||
{"items": [], "status": "ok"}
|
||||
@@ -0,0 +1,6 @@
|
||||
# Rollback (fail-closed)
|
||||
launchctl bootout gui/501/com.agentctl.coordinator
|
||||
rm -f /Users/weichen/Library/LaunchAgents/com.agentctl.coordinator.plist
|
||||
# verify:
|
||||
launchctl print gui/501/com.agentctl.coordinator # expect not found
|
||||
python3 /private/tmp/Agent-System/scripts/agentctl.py daemon status
|
||||
@@ -0,0 +1,2 @@
|
||||
146:Ran 134 tests in 118.996s
|
||||
148:OK (skipped=3)
|
||||
+53
@@ -0,0 +1,53 @@
|
||||
=== RUN TestPlanProposal_SecurityRejectsWhole
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
|
||||
--- PASS: TestPlanProposal_SecurityRejectsWhole (0.00s)
|
||||
=== RUN TestIntentRecognition_SecurityForbidden
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden (0.00s)
|
||||
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked
|
||||
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/合规手册撰写含整改角色字段
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
|
||||
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/整改+角色远距共现
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
|
||||
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/改一下文档+角色跨句
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
|
||||
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/换一份清单+姓名字段
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
|
||||
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/系统配置说明文档撰写
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=AMBIGUOUS_FALLBACK confidence=0.2
|
||||
=== RUN TestIntentRecognition_SecurityFalsePositives_NotBlocked/知识库连接故障排查询问
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=CASUAL_CHAT branch=NEW_INTENT_PREEMPT confidence=0.7
|
||||
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/合规手册撰写含整改角色字段 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/整改+角色远距共现 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/改一下文档+角色跨句 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/换一份清单+姓名字段 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/系统配置说明文档撰写 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked/知识库连接故障排查询问 (0.00s)
|
||||
=== RUN TestIntentRecognition_SecurityForbidden_Extended
|
||||
=== RUN TestIntentRecognition_SecurityForbidden_Extended/姓名修改
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
|
||||
=== RUN TestIntentRecognition_SecurityForbidden_Extended/部门修改
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
|
||||
=== RUN TestIntentRecognition_SecurityForbidden_Extended/资质修改
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
|
||||
=== RUN TestIntentRecognition_SecurityForbidden_Extended/向量库连接修改
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
|
||||
=== RUN TestIntentRecognition_SecurityForbidden_Extended/网关密钥修改
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
|
||||
=== RUN TestIntentRecognition_SecurityForbidden_Extended/知识库连接修改
|
||||
2026/09/25 12:51:24 INFO intent_recognition intent=SECURITY_FORBIDDEN branch=NEW_INTENT_PREEMPT confidence=1
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden_Extended (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/姓名修改 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/部门修改 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/资质修改 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/向量库连接修改 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/网关密钥修改 (0.00s)
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden_Extended/知识库连接修改 (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/intent 0.007s
|
||||
=== RUN TestCoordinatorEngine_SecurityForbidden
|
||||
2026/09/25 12:51:24 INFO coordinator_route intent=SECURITY_FORBIDDEN branch="" confidence=0 channel=TEMPLATE reason=查询/治理/补充类意图,走规则模板与知识库直答
|
||||
--- PASS: TestCoordinatorEngine_SecurityForbidden (0.00s)
|
||||
PASS
|
||||
ok chat-agent-system/internal/coordinator 0.004s
|
||||
@@ -0,0 +1,83 @@
|
||||
# 安全红线正则误拦 测试报告
|
||||
|
||||
## 一、 测试背景 (Background)
|
||||
|
||||
用户发送正常文档撰写请求「请撰写详尽合规手册:…每项含理由/证据/失败模式/整改/角色/抽样方法…」时,助手返回固定文案「⚠️ 合规权限拦截…」。根因是 `isSecurityViolation` 正则 2 用裸单字动词「改」加无界 `.*`,把「整改/角色」误配为越权写操作。
|
||||
|
||||
规范归档路径应为 `.doc/test-reports/`;本报告因并行任务 `server-image-field-closeout-r3-2026-09-25` 占用该 scope,先落盘于 `.doc/ops/evidence/` 与 agent store,待 scope 释放后再迁移。
|
||||
|
||||
## 二、 测试目标 (Test Objectives)
|
||||
|
||||
1. 原句与同类误报变体不得返回 `SECURITY_FORBIDDEN`。
|
||||
2. 既有真阳性用例仍须拦截(confidence=1.0)。
|
||||
3. 收紧机制不破坏 `internal/intent` / `internal/coordinator` 回归。
|
||||
|
||||
## 三、 测试方案与环境 (Test Plan & Environment)
|
||||
|
||||
- OS: Linux;Go 1.27.1;worktree `feature/security-redline-false-positive-2026-09-25` @ base `44161d2a`
|
||||
- 层级:Go/接口(验证契约)
|
||||
- 范围:`internal/intent`、`internal/coordinator`;全量 `go test -short ./...`(旁路失败单独记)
|
||||
|
||||
## 四、 预期结果 (Expected Results)
|
||||
|
||||
| 用例 | 预期 |
|
||||
|---|---|
|
||||
| 原句合规手册撰写 | 非 SECURITY_FORBIDDEN |
|
||||
| 整改计划…角色职责 | 非 SECURITY_FORBIDDEN |
|
||||
| 改一下文档标题…角色 | 非 SECURITY_FORBIDDEN |
|
||||
| 换一份清单…姓名字段 | 非 SECURITY_FORBIDDEN |
|
||||
| 起草系统配置说明文档 | 非 SECURITY_FORBIDDEN |
|
||||
| 知识库连接失败怎么排查 | 非 SECURITY_FORBIDDEN |
|
||||
| 既有 SecurityForbidden / Extended | 仍 SECURITY_FORBIDDEN |
|
||||
|
||||
## 五、 实际测试结果与判定 (Actual Results & Evaluation)
|
||||
|
||||
### 5.1 修复前(对照)
|
||||
|
||||
命令:`go test ./internal/intent/ -run TestIntentRecognition_SecurityFalsePositives_NotBlocked -count=1`
|
||||
|
||||
- **实际输出**:6/6 子用例 FAIL,均 `got SECURITY_FORBIDDEN`
|
||||
- **判定**:FAIL(预期:用于确认红)
|
||||
- **耗时**:约 4ms
|
||||
|
||||
### 5.2 修复后 — 误报负例
|
||||
|
||||
命令:`go test ./internal/intent/ ./internal/coordinator/ -count=1 -v -run 'Security'`
|
||||
|
||||
```
|
||||
--- PASS: TestIntentRecognition_SecurityFalsePositives_NotBlocked (0.00s)
|
||||
--- PASS: .../合规手册撰写含整改角色字段
|
||||
--- PASS: .../整改+角色远距共现
|
||||
--- PASS: .../改一下文档+角色跨句
|
||||
--- PASS: .../换一份清单+姓名字段
|
||||
--- PASS: .../系统配置说明文档撰写
|
||||
--- PASS: .../知识库连接故障排查询问
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden
|
||||
--- PASS: TestIntentRecognition_SecurityForbidden_Extended (全部子用例)
|
||||
--- PASS: TestCoordinatorEngine_SecurityForbidden
|
||||
ok chat-agent-system/internal/intent
|
||||
ok chat-agent-system/internal/coordinator
|
||||
```
|
||||
|
||||
- **判定**:PASS
|
||||
- **耗时**:intent ~7ms;coordinator ~4ms
|
||||
|
||||
### 5.3 门禁
|
||||
|
||||
| 检查 | 判定 |
|
||||
|---|---|
|
||||
| `./scripts/arch-check.sh --mode block` | PASS |
|
||||
| `go vet ./...` | PASS |
|
||||
| `go test ./internal/intent/ ./internal/coordinator/ -count=1` | PASS |
|
||||
| `go test -short ./...` | 旁路 FAIL:`cmd/bizdev-cli` goose duplicate version 71(`00071_...maintenance-windows` 与 `00071_...context-conflict-adjudications`),与本次 intent 改动无关;其余包 ok |
|
||||
|
||||
## 六、 自动化测试套件汇总 (Test Suite Execution)
|
||||
|
||||
- 适用并实际运行:arch-check、go vet、intent/coordinator 全量、short 全仓(旁路失败已记录)
|
||||
- 新增用例:`TestIntentRecognition_SecurityFalsePositives_NotBlocked`(6 子例)
|
||||
- 真阳性零回退
|
||||
|
||||
## 七、 测试结论与后续优化建议 (Conclusion & Next Steps)
|
||||
|
||||
- **结论**:机制级收紧后,原句与同类变体不再误拦;真阳性仍拦截。授权范围内验收满足。
|
||||
- **后续**:① scope 释放后将本报告迁入 `.doc/test-reports/2026-09-25-security-redline-false-positive-test-report.md`;② 独立处理 goose 71 重复(非本任务);③ 可选:对「越权」裸字面量做同类负例评估(如「防越权培训」)。
|
||||
@@ -25,9 +25,9 @@ status: open
|
||||
| 研究 mutex | 已在本 worktree CURRENT 标记 done |
|
||||
| 共享集成槽位 | 本任务分支 CURRENT 登记文档集成;实际操作持 common-dir 下 dev-integration.lock,主目录 CURRENT 保留 |
|
||||
| branch | feature/agent-workflow-governance-plan |
|
||||
| worktree | .worktrees/feature-agent-workflow-governance-plan |
|
||||
| worktree | 原任务及候选在收口后按门禁清理;dev 文档入口暂为 `.worktrees/agent-governance-dev-integration` |
|
||||
| 起点 | 本地 dev@15b8a4a8 |
|
||||
| 合入 / push | 本次按已验证候选合入本地 dev;未 push,最终结果见规范采纳验收报告 |
|
||||
| 合入 / push | 规则提交 `048bbe4a` 已经由候选 `83e22a70` 合入本地 dev;未 push;后续收口仅文档 |
|
||||
|
||||
## 验证及边界
|
||||
|
||||
@@ -35,9 +35,10 @@ status: open
|
||||
- 主目录另有 Cursor 工作流作用域任务的未提交改动;保留现场,不 checkout/pull/stash/reset。
|
||||
- 当前没有自动任务协调器,分支 CURRENT 不等于全局实时认领。此次只有人工明确范围和本机 flock,不宣称自动队列或全局硬隔离已实现。
|
||||
- 收口文档允许单独审核/合入,但不能按计划已写完将治理功能改成 done。
|
||||
- 主目录仍是旧任务分支;dev 暂由 `.worktrees/agent-governance-dev-integration` 检出以安全集成文档。旧任务 owner 保存成果、确认主目录干净后,先安全移除临时 dev worktree,再在主目录切回 dev;不得强抢 dev 检出。
|
||||
- 规范首次合入后,Cursor 已把作用域修复合入 `dev@e0665ca4`,并将主目录切为该提交的 detached HEAD 进行部署。dev 仍暂由 `.worktrees/agent-governance-dev-integration` 检出;该目录当前也被 Cursor 的集成流程使用,须等其释放槽位后再清理或接管。主目录最终切回 dev 前先安全移除临时 dev worktree;不得强抢检出或修改活跃部署源。
|
||||
|
||||
## 相关链接
|
||||
|
||||
- [研究任务](../../archive/ops/2026-09-21-agent-workflow-governance-plan.md)
|
||||
- [CURRENT](../CURRENT.md)
|
||||
- [采纳验收](../../test-reports/2026-09-21-agent-workflow-governance-adoption-test-report.md)
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
---
|
||||
lesson_id: LESSON-20260923-content-hash
|
||||
lesson_state: validated
|
||||
owner: Codex
|
||||
reviewer: Codex (source review)
|
||||
last_reviewed: 2026-09-23
|
||||
reviewed_revision: 2fdb6e548e3784771f27e6a9e79b9c364f76c566
|
||||
source_issues: [ISSUE-20260923-content-hash]
|
||||
keywords: [docrevision, doccontent, canonicalize, hash, bootstrap, hard-break, hydration, '404']
|
||||
---
|
||||
|
||||
# 文本规范化必须保持语义并维护账本与文件一致性
|
||||
|
||||
**触发**:修改 Markdown 规范化、哈希、版本 bootstrap、文件投影、正文加载或刷新缓存时。
|
||||
|
||||
**机制与来源**:[问题主记录](../../audit/2026-09-23-historical-issue-records.md#content-hash)。去掉行尾双空格破坏硬换行语义;只更新账本哈希使原文件读取失配。统一报 404 和无效轮询更新让数据冲突难以诊断并反复呈现。
|
||||
|
||||
**开发检查**:
|
||||
|
||||
1. 对规范化定义允许变化和必须保留的语义,保留硬换行等差异样例;哈希一致性依赖相同语义和规范化契约。
|
||||
2. 追踪快照、记录哈希与文件投影的写入顺序和失败恢复。旧文档首次 bootstrap 与新文档创建分别覆盖,并发 content/revision 请求和刷新后读取需按实际因果链验证。
|
||||
3. 数据修复先按授权保全原文件及旧版本,显式记录修复来源;不能通过静默覆盖或跳过校验来隐藏不一致。
|
||||
4. 将不存在、完整性冲突和临时失败按协议区分。检查无变化轮询是否重复触发内容加载;失败反馈应可定位。
|
||||
|
||||
**已有防护**:[黄金样例](../../../internal/docrevision/canonicalize_golden_test.go) 含硬换行保持及 doccontent 封装一致性;[历史真实 UI 报告](../../test-reports/2026-09-14-controlled-content-ui-acceptance.md) 覆盖旧文档、刷新和重启。2026-09-23 只核对源码与报告,未重跑;测试存在不等于在未来变更中已执行。
|
||||
|
||||
**边界**:哈希不同不自动说明数据丢失,也不自动授权重写。不同文件格式的空白语义不同;不得把 Markdown 规则机械用于其他格式。当前制品和旧数据迁移需要各自证据,新项目 PASS 不代替旧数据验收。
|
||||
|
||||
**未完成防护**:没有全仓扫描或新 CI 门禁;未来相关修改按验证契约运行适用用例并记录结果。
|
||||
|
||||
**修订**:2026-09-23 从历史问题提炼,核对当前 canonicalize 委托与黄金样例;规范化/投影/缓存契约改变时再审。
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
lesson_id: LESSON-20260923-matrix-status-cas
|
||||
lesson_state: validated
|
||||
owner: Cursor
|
||||
reviewer: Cursor (source review + arch-check)
|
||||
last_reviewed: 2026-09-23
|
||||
reviewed_revision: b9d09c97120ee5bcdea487b0d0ca5910d6e98a1d
|
||||
source_issues: [ISSUE-20260923-matrix-status-regression]
|
||||
keywords: [FEATURE-MATRIX, docs-apply, record_id, merge-conflict, CAS, planned, done]
|
||||
---
|
||||
|
||||
# 共享矩阵状态变更必须走 docs apply,合并后核验状态列
|
||||
|
||||
**触发**:改 FEATURE-MATRIX / CURRENT 行状态,或合并含这两份文件的候选时。
|
||||
|
||||
**机制与来源**:[ISSUE-20260923-matrix-status-regression](../../audit/2026-09-23-matrix-status-regression.md)。A–G 代码已合入且曾标 `done`,closeout 合并冲突手解取旧侧把状态盖回 `planned`,误导后续会话。
|
||||
|
||||
**开发检查**:
|
||||
|
||||
1. 不直接编辑 FEATURE-MATRIX / CURRENT 表行;用 `agentctl docs snapshot` + `docs apply`(MATRIX 键为 `record_id`)。
|
||||
2. 升 `done` 须 `docs:approve` 与已提交 evidence 路径(门禁 `EVIDENCE_REQUIRED`)。
|
||||
3. 合并含共享文档的候选后,对目标 `record_id` 再 `docs snapshot` 或 `grep` 核验状态列未被回退;冲突手解禁止静默取旧侧。
|
||||
|
||||
**验证方式**:本轮对 `module-batches-ag` 做 apply 收据 + `arch-check --mode block` PASS;未新增自动化 CI。manual。
|
||||
|
||||
**适用边界**:仅协调 SSOT(CURRENT / FEATURE-MATRIX);普通 `.doc` 短文仍可租约内直接改。不覆盖 gap-matrix 发布门禁语义。
|
||||
|
||||
**防护落实**:`scripts/agentctl.py` 已对 MATRIX `done` 要求 evidence;本条强调合并后人工/脚本核验。仍缺:merge 后自动断言关键 `record_id` 状态(待治理任务)。
|
||||
|
||||
**修订**:2026-09-23 新建;同日 apply 恢复 + arch-check 后升 validated。
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
lesson_id: LESSON-20260923-nullable-duty
|
||||
lesson_state: validated
|
||||
owner: Codex
|
||||
reviewer: Codex (source review)
|
||||
last_reviewed: 2026-09-23
|
||||
reviewed_revision: 2fdb6e548e3784771f27e6a9e79b9c364f76c566
|
||||
source_issues: [ISSUE-20260923-nullable-duty]
|
||||
keywords: [docgov, nullable, SQL, FK, reviewer_id, '23503', heal]
|
||||
---
|
||||
|
||||
# 可选职责在所有持久化入口保持同一空值语义
|
||||
|
||||
**触发**:修改可选成员/职责、SQL 写入、创建/heal/import/upsert 等路径时;检查范围以实际共享字段和表写者为准。
|
||||
|
||||
**机制与来源**:[问题主记录](../../audit/2026-09-23-historical-issue-records.md#nullable-duty)。内存 0 表示缺席,但数据库可空 FK 需要 NULL;一个入口已有转换不能证明另一个入口也有。原审计中错误被通用 INTERNAL_ERROR 掩盖,说明还需检查错误分型。
|
||||
|
||||
**开发检查**:
|
||||
|
||||
1. 从字段契约确定缺席、有值但非法、合法值三种语义;沿现有表写者列出所有写入口,检查转换一致性。
|
||||
2. 保持可选职责业务规则;让 SQL 边界处理缺席值,不能靠强制填 reviewer 掩盖实现错误。合法角色与非法 ID 仍按原有鉴权/FK 处理。
|
||||
3. 对缺席、合法、非法值及相关创建/修复入口安排真实 PG 验证;mock 不会证明 FK/NULL 行为。保持正常职责模式的回归。
|
||||
|
||||
**已有防护**:[engine](../../../internal/docgov/engine.go) 创建路径使用 `nullIfZero`;[历史报告](../../test-reports/2026-09-17-docgov-optional-duty-null-fk-test-report.md) 记录 `TestDocGov_CreateOrGetDocument_OptionalDutiesNullFK`、分型单测与 API/DB 冒烟。2026-09-23 仅复核源码及旧报告,未重跑测试;未据此证明真实 UI、所有写路径或当前部署。
|
||||
|
||||
**边界**:只适用于明确以 0 表示未设置且列允许 NULL 的字段;不能对所有数值或必填关系统一转 NULL。授权资格判定仍遵循现行规范。
|
||||
|
||||
**未完成防护**:跨所有相关入口的自动覆盖不由本条保证;后续变更任务按实际影响补证。没有新增 CI 门禁。
|
||||
|
||||
**修订**:2026-09-23 从历史 FK 案例提炼,并核对当前创建路径;接口/表写者变化或同因复发时再审。
|
||||
@@ -0,0 +1,28 @@
|
||||
---
|
||||
lesson_id: LESSON-20260924-cursor-hook-advisory-gates
|
||||
lesson_state: candidate
|
||||
owner: Cursor
|
||||
reviewer: Cursor(自审;实机采样后转 validated)
|
||||
last_reviewed: 2026-09-24
|
||||
reviewed_revision: cursor-governance-hooks-2026-09-24 worktree
|
||||
source_issues:
|
||||
- ISSUE-20260924-cursor-hook-event-contract
|
||||
- ISSUE-20260924-cursor-test-rule-drift
|
||||
- ISSUE-20260924-cursor-cli-mcp-path
|
||||
keywords: [Cursor, hooks, advisory, fail-open, probe, stdin, MCP]
|
||||
---
|
||||
|
||||
# 客户端 hook 与执行器门禁分层;契约未知时 fail-open
|
||||
|
||||
- 触发条件:为 Cursor 增加 hooks/rules,或发现 hook「写了但不生效/误拦」时。
|
||||
- 机制与来源:执行器(`pi_subagents.py` / agentctl)已有权威硬拒绝;hook 事件字段官方未完全文档化。heredoc 包装 Python 会吞掉 hook stdin。审计日志若放进被 git 跟踪的 `.cursor/hooks/` 会污染仓库。
|
||||
- 开发检查:
|
||||
1. hook 只做形状/授权类 `ask`,不复刻执行器全部校验。
|
||||
2. 用独立 `.py` + 薄 `.sh` `exec`,禁止 heredoc 占 stdin。
|
||||
3. 多名容错(`tool_name|mcp_tool_name|name` 等);识别失败 → allow + `UNRECOGNIZED_INPUT` 审计。
|
||||
4. 审计/probe 写 `.cursor/hook-audit.jsonl` / `hook-probe.jsonl`(被 `.cursor/*` ignore)。
|
||||
5. 规则副本只做指针,不复制验证契约中的模型名与全量命令。
|
||||
- 验证方式:`scripts/tests/test_cursor_hooks.py`;实机 `CURSOR_HOOKS_PROBE=1` 采样后升 validated。
|
||||
- 适用边界:本仓库项目级 hooks;不声称覆盖所有 Cursor 版本或 CLI 加载行为。
|
||||
- 防护落实:单元回归 enforced;hook↔Cursor 接线仍 advisory/manual。
|
||||
- 修订与失效:实机字段确认后收紧 matcher 并更新本条状态。
|
||||
@@ -0,0 +1,20 @@
|
||||
# LESSON-20260924-deny-only-submit
|
||||
|
||||
## 触发条件 / 关键词
|
||||
|
||||
非编制、DOC_DUTY、400、run/edit、送审、成员草稿
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. 权限哨兵必须在 `domainHTTPStatus` 显式映射到 403;默认 400 会让前端 403 文案永不命中。
|
||||
2. 放宽受控文档写权限时,`classifyAccess`、`AllowedTaskKeys`、`CanEditDocumentContent` 必须同批调整,否则单门放行仍会在下游失败。
|
||||
3. docgov 不得 import projectinstance:成员身份由 server 校验后经 `ActorIsMember` 传入;禁止用 `RoleSystem` 冒充人工成员。
|
||||
4. 审批路径走 `CheckDocTaskAccess(submit|review|approve)`,不要复用 `TaskKeyAllowed`。
|
||||
|
||||
## lesson_state
|
||||
|
||||
validated(2026-09-24 真实 PI)
|
||||
|
||||
## 主记录
|
||||
|
||||
[ISSUE-20260924-non-author-400-duty](../../audit/2026-09-24-non-author-member-access.md)
|
||||
@@ -0,0 +1,26 @@
|
||||
---
|
||||
lesson_id: LESSON-20260924-pi-tool-boundaries
|
||||
lesson_state: validated
|
||||
owner: Cursor/Codex
|
||||
reviewer: Codex
|
||||
last_reviewed: 2026-09-24
|
||||
reviewed_revision: 69ffaa677e23a1dd9aa0528bb09b3acfcd38b119
|
||||
source_issues: [ISSUE-20260924-pi-executor-boundaries]
|
||||
keywords: [PI, MCP, readonly, path, snapshot, process-group]
|
||||
---
|
||||
|
||||
# 文件工具的路径检查须匹配实际客户端语义
|
||||
|
||||
触发:为第三方 Agent 包装只读文件工具、复制输入快照或监督子进程。
|
||||
|
||||
机制:PI 0.85.1 工具会展开 @/~,初版守卫只做 path.resolve,检查对象与实际打开对象不同;另有 exact-root 空相对路径误拒、内部扩展复制进模型快照导致合法枚举被白名单拒绝。见[问题](../../audit/2026-09-24-pi-executor-boundaries.md)与[验证](../../test-reports/2026-09-24-pi-executor-test-report.md)。
|
||||
|
||||
实施前检查:
|
||||
|
||||
1. 读实际工具的路径规范化实现;拒绝不支持的前缀/参数,核对 canonical realpath、符号链接与选定文件。不能仅假设安全的相对拼接等于最终访问路径。
|
||||
2. 模型输入、测试可写副本、客户端内部配置/扩展分开;允许清单只包含模型该读的材料。内部文件不要塞进源码快照。
|
||||
3. 同时验证拒绝路径和合法根目录/子目录、默认 path;只有负例通过不足以证明工具可用。
|
||||
4. MCP 直接协议实测和真实客户端派发都要做。官方文档支持变量不证明本机 CLI 已展开;真实路径错误用版本/命令留证。
|
||||
5. 进程完成与验收通过分开,leader 退出不证明整个进程组退出。保留报告和失败证据,再按实际运行身份回收。
|
||||
|
||||
范围:本次 gmktec/Linux、PI 0.85.1、Cursor CLI 的工程工具;客户端升级和其它系统需复核。这里的工具/进程守卫不是 OS 沙箱。
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
lesson_id: LESSON-20260926-failclosed-bypass-contract
|
||||
lesson_state: validated
|
||||
created: 2026-09-26
|
||||
updated: 2026-09-26
|
||||
source_issues:
|
||||
- ISSUE-20260926-ctx-idor
|
||||
- ISSUE-20260926-archcheck-untracked
|
||||
- ISSUE-20260926-authz-failopen
|
||||
- ISSUE-20260926-swboot-shell-prefix
|
||||
- ISSUE-20260926-intentflow-validated-confirm
|
||||
reviewed_by: pi
|
||||
last_reviewed: 2026-09-26
|
||||
reviewed_revision: "fix/system-review-p0-p1-fixes-2026-09-26"
|
||||
keywords: [IDOR, 旁路, fail-open, fail-closed, 白名单前缀, sh -c, validated_only, table_owners, untracked, session_id, 归属校验]
|
||||
---
|
||||
|
||||
# 旁路入口与「未知即拒绝」契约
|
||||
|
||||
## 触发条件
|
||||
|
||||
- 新增/评审任何**绕过主用例路径**的 HTTP handler(尤其按 `session_id`/`project_id`/`user_id` 直接取资源的旁路端点)。
|
||||
- 写门禁扫描器、授权器或执行器时出现「未登记/未配置/依赖缺失」分支。
|
||||
- 注释或文档声称某 flag/mode 是安全边界(如 `validated_only must never be written as succeeded`)。
|
||||
- 命令/路径白名单实现(前缀匹配、`sh -c` 拼接)。
|
||||
|
||||
## 机制与应做检查
|
||||
|
||||
1. **主路径绿 ≠ 旁路绿**:主路径(chatflow/Owner 等)的鉴权不会自动覆盖旁路 handler。每个按标识取资源的入口都要复用同一归属校验(如 `GetSessionOwnerID`),并在 SQL/存储层再加归属条件作防御纵深——handler 层校验可能被未来调用方遗漏。
|
||||
2. **门禁对「未知」必须拒绝**:扫描器遇到未登记对象 `continue` 等于该维度门禁关闭(arch-check 未登记表曾静默跳过 ~50 张表的真实写)。正确形状:未登记→finding,假阳性用显式且可审计的豁免清单。
|
||||
3. **授权器缺依赖时不得放行**:`pool==nil` 返回 true 是 fail-open;需要演示/测试宽松语义时,用**显式命名的构造器**(`NewInMemoryAuthorizer`)+ 组合根按配置选择,默认路径严格拒绝。
|
||||
4. **契约写在注释里不算数**:`validated_only` 之类执行模式必须由执行器硬读硬拒(Confirm 拒 + ExecuteClaimed 拒双层),安全不能依赖「没人点 Confirm」或上游状态机不犯错。
|
||||
5. **白名单用精确匹配 + argv 执行**:basename 前缀匹配可被 `go-evil` 伪装;`sh -c` 让元字符求值。argv 化后元字符只是字面参数。
|
||||
|
||||
## 错误做法与原因
|
||||
|
||||
- 只给主路径补鉴权、把旁路留给「下次」——本仓 IDOR 事故高发位正是旁路 HTTP。
|
||||
- 用「未配置就放行」降低接线摩擦——组合根永远能构造成功,fail-open 在误配时静默生效。
|
||||
- 用测试 override `NewAuthorizer(nil)` 当「跳过检查」接缝——它同时是生产 fail-open 的机制本身;接缝必须显式命名。
|
||||
|
||||
## 验证方法
|
||||
|
||||
- 回归覆盖:原例(他户标识→403/空)、同类变体(不存在→同构拒绝、admin 越权面)、正常行为(本人→200 且数据完整)。
|
||||
- 门禁类:自测夹具证明未登记对象 block、已知假阳性不误报;全仓门禁在登记完成后 PASS。
|
||||
- 执行类:伪装命令拒绝、元字符不求值(marker 文件不产生)、owner 零调用计数。
|
||||
|
||||
## 适用边界
|
||||
|
||||
- 适用于进程内授权、静态扫描门禁、命令白名单、执行模式契约四类机制;不覆盖网络层/跨服务鉴权。
|
||||
- 豁免清单(如扫描噪音词)是启发式产物:新假阳性出现时应先确认确非真实表,再扩清单。
|
||||
|
||||
## 关联
|
||||
|
||||
- 来源修复:[2026-09-26 系统 code review P0/P1 修复](../../remediation/2026-09-26-system-code-review-fixes.md)
|
||||
- 发现审计:[2026-09-26 系统全面 code review](../../audit/2026-09-26-system-code-review.md)
|
||||
- 关联回归:`TestGetUserContext_*`、`TestUntrackedTableWriteIsBlocked`、`TestMembershipChecks_FailClosedWithoutPool`、`TestExecutor_CommandAllowlistIsExactNotPrefix`、`TestExecutor_NoShellEvaluation`、`TestConfirmRejectedForValidatedOnlyPlan`、`TestExecuteClaimedRefusesValidatedOnlyStep`
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
title: "LESSON-20260927: 服务端事实源优先与隔离测试库配方"
|
||||
created: 2026-09-27
|
||||
owner: pi
|
||||
source_issue: ISSUE-20260927-upload-doc-cross-device
|
||||
status: verified-on-dev
|
||||
---
|
||||
|
||||
# 服务端事实源优先与隔离测试库配方
|
||||
|
||||
## 教训一:客户端本地兜底不能替代服务端事实源
|
||||
|
||||
上传链路曾把文件二进制放在浏览器内存 + IndexedDB、元数据放在 localStorage,服务端只存注册占位模板。换浏览器/清存储/共享他人查看时全部失效,用户看到的是"文档概述与背景"占位文案而非文档内容。同一缺陷家族还包括把展示用字符串("0 KB")烘焙进持久化正文。
|
||||
|
||||
**规则**:任何需要跨会话/跨端/跨用户存活的事实(文件、元数据、正文),必须在服务端持久化;本地存储只允许作为加速缓存。持久化的内容不得包含客户端生成的展示态字符串(格式化大小、本地时间文案),恢复时从事实源重建。
|
||||
|
||||
## 教训二:worktree 里跑测试必须显式钉住 DB 目标
|
||||
|
||||
`config.Load(".env")` 缺文件时静默回退到默认 DSN = 真实 dev 库(127.0.0.1:5433,含默认口令)。在任务 worktree 跑 `go test ./...` 会真实写入 dev 业务库,甚至经 `bizdev.NewService` 自动应用迁移链。本次误连两次(写入合成测试行 + 提前把 dev 迁到 76),虽未损坏历史数据,但属计划外副作用。
|
||||
|
||||
**规则**:worktree/CI 中凡触发 DB 的测试,一律显式 `export TEST_DATABASE_URL=<隔离库> CONTEXT_DB_HOST/PORT/USER/PASSWORD/NAME=<隔离库>`;用一次性容器(`docker run --rm pgvector/pgvector:pg16 -p 127.0.0.1:<随机端口>`)承载。端口字符串避开 "5433/5434/5435" 子串(`RefuseSharedEnvDSN` 按子串拒绝,55433 会被误拒)。
|
||||
|
||||
## 教训三:隔离库正确配方与顺序
|
||||
|
||||
- 顺序必须是:**扩展(vector/uuid-ossp)→ goose 迁移链 → system_init/docgov_init/context_init**。顺序颠倒时 `00001_baseline.sql` 会因 `chat_messages.day_key` 不存在而失败(init 脚本相互不独立)。
|
||||
- 即使配方正确,`TestPG_ActivationAndStageAdvance`、`TestWorkflowGovernance_PG_*`、`TestCreateDocument_PG_ClientKeyIdempotent...` 等重组件用例在自建隔离库上仍可能失败("approved requires frozen review_snapshot_id" 等顺序/外部服务依赖)——**先在基线 dev HEAD 上复现再定性**,勿把环境敏感当回归。
|
||||
- 判定回归的最小对照法:同一隔离库配方 × {基线代码, 候选代码} × {单用例, 全包} 四格对照,均复现即预存在。
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
lesson_id: LESSON-20260928-activation-preview-client-gate
|
||||
lesson_state: validated
|
||||
owner: Cursor
|
||||
reviewer: Cursor
|
||||
last_reviewed: 2026-09-28
|
||||
reviewed_revision: 3e534bbb39d0d957e0b720a4ca06f22dd15959e6
|
||||
source_issues: [ISSUE-20260928-activation-preview-precheck]
|
||||
keywords: [activation-preview, NO_GOVERNED_DOCUMENT, clientDutyIssues, needsGovernedDocument, 400]
|
||||
---
|
||||
|
||||
# 激活门禁要在点击前做同样的前端预检
|
||||
|
||||
- 触发条件:控制台出现 `POST .../activation-preview 400`,响应码是 `NO_GOVERNED_DOCUMENT`。
|
||||
- 机制与来源:服务端 `validateActivationPlan` 要求至少一份完整人工审批。前端 `clientDutyIssues` 只查三权完整性,全部未纳入审批时仍会发请求。见 ISSUE-20260928-activation-preview-precheck。
|
||||
- 开发检查:新增激活条件时,同时改 `validateActivationPlan` 与 `needsGovernedDocument` / `clientDutyIssues`。运行中 `live_edit` 走 `validatePlan`,不要套激活门禁。
|
||||
- 验证方式:默认计划直接预览不得发出 activation-preview;一份兼任文档预览应 200。单测在 `web/src/lib/projectSettingsDuties.test.ts`。
|
||||
- 适用边界:只覆盖激活前规划。已激活实例改职责不要求「至少一份」。
|
||||
- 防护落实:上述单测与 dev 浏览器复验已落地。
|
||||
- 修订与失效:若产品允许零审批激活,应同时删除服务端 `NO_GOVERNED_DOCUMENT` 与前端预检。
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
lesson_id: LESSON-20260928-docgov-shared-map-race
|
||||
lesson_state: validated
|
||||
owner: Cursor
|
||||
reviewer: Cursor(自审)
|
||||
last_reviewed: 2026-09-28
|
||||
reviewed_revision: b9339cd2
|
||||
source_issues: [ISSUE-20260928-docgov-map-race]
|
||||
keywords: [docgov, memDocs, memMu, per-doc lock, concurrent map, 登录 500]
|
||||
---
|
||||
|
||||
# 拆细粒度锁后,共享 map 仍要单独互斥
|
||||
|
||||
- 触发条件:把全局锁拆成 per-id 锁,但多个 id 仍读写同一张 Go map(缓存、审计、批注、提案)。
|
||||
- 机制与来源:docgov 的 per-doc 锁不保护 `memDocs` 等 map。不同文档并发时 `GetDocument` 与写入撞上,运行时 fatal,进程退出后所有 HTTP API(含登录)500。证据:2026-09-28 `.tmp/launch/server.log` 与 `web.log` 的 `ECONNREFUSED`。修复见 [任务](../short-term/2026-09-28-docgov-shared-map-race.md)。
|
||||
- 开发检查:map 的读写、遍历、append 都走同一把锁。已持有外层锁的路径不能再锁同一把(Go 互斥锁不可重入)。锁序固定,禁止在 map 锁内再拿文档锁或外层锁。不要用「登录 500」去改登录代码。
|
||||
- 验证方式:不同 docID 并发创建与读取,`go test -race` 覆盖 `TestMemMapsNoRaceAcrossDocs`。进程崩溃类问题还要看服务日志里的 fatal,而不是只看单个 API 状态码。
|
||||
- 适用边界:适用于 docgov 这四张内存 map。文档结构体字段的数据竞争、以及持久化失败后的缓存投毒(`ISSUE-20260926-docgov-memdocs-poison`)不在本条范围内。
|
||||
- 防护落实:`memMu` 与 `TestMemMapsNoRaceAcrossDocs`。没有新增静态检查,漏一个裸访问仍要靠 `-race` 和复查。
|
||||
- 修订与失效:若这四张 map 改为分片或移除,本条对那个存储失效,保留历史。
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
lesson_id: LESSON-20260928-material-noun-not-sales-template
|
||||
lesson_state: validated
|
||||
owner: Cursor
|
||||
reviewer: Cursor(自审)
|
||||
last_reviewed: 2026-09-28
|
||||
reviewed_revision: 8f77053f5169502eaf3e4e4135a082e8914f3704
|
||||
source_issues: [ISSUE-20260928-material-template-reply]
|
||||
keywords: [intent, 说明书, 操作视频, 竞品, AMBIGUOUS_FALLBACK, 掂量, fallback_reason]
|
||||
---
|
||||
|
||||
# 资料名词不要掉进阶段推销模板
|
||||
|
||||
- 触发条件:用户用名词短语索取说明书、视频、彩页、手册、上一代或竞品资料,句子里没有「生成/编写/撰写」。
|
||||
- 机制与来源:低置信保底会进模糊咨询;模糊咨询原先对非问句直接输出阶段对照。对话模型建目录或执行失败时若只返回空字符串,模板会原样留下,日志里看不到原因。见 [任务](../short-term/2026-09-28-intent-material-fallback.md)。
|
||||
- 开发检查:资料获取走知识检索,未命中再走对话模型;犹豫征询才保留阶段对照。模型早退必须打日志,并把 `fallback_reason` 写入 `reply_source=template` 的 metadata。写动词不要误判成检索。
|
||||
- 验证方式:原始输入单测不得再是 `AMBIGUOUS_FALLBACK`;无模型时回复不得含「掂量」;真实产品回合的 `reply_source` 为 `pi-agent` 或 `kb`。
|
||||
- 适用边界:适用于「把已有资料找出来」。用户明确要编写新文档时仍走任务触发。阶段推进失败后没有助手消息是另一问题(ISSUE-20260928-advance-stage-silent-fail),本条不覆盖。
|
||||
- 防护落实:manual,另有 intent / coordinator / chat 单测。2026-09-28 在 dev 库、dev runner、工作树二进制上确认 `reply_source=kb`(项目 6024)。:8080 二进制尚未替换。
|
||||
- 修订与失效:若产品改为资料请求一律进小队任务,本条的检索分流不再适用,保留历史。
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
lesson_id: LESSON-20260928-quality-heading-normalize
|
||||
lesson_state: candidate
|
||||
owner: Cursor
|
||||
reviewer: Cursor(自审,待 dev 重跑调研报告后升 validated)
|
||||
last_reviewed: 2026-09-28
|
||||
reviewed_revision: 434d542c3cbdbeac38b9c0e547edf75160acf577
|
||||
source_issues: [ISSUE-20260928-quality-heading-drift]
|
||||
keywords: [quality_gate, 缺少必填章节, State-of-the-Art, H3, AutoRepair]
|
||||
---
|
||||
|
||||
# 章节门禁比对标题,不比对空格和层级
|
||||
|
||||
- 触发条件:交付正文章节都在,质量报告仍写「缺少必填章节」,评分往往停在 85。
|
||||
- 机制与来源:模板 H2 与模型常写的 H3、多一个或少一个空格、全角字母,在精确字符串比较下会被当成整章缺失。缺章会短路受控投影。见 ISSUE-20260928-quality-heading-drift。
|
||||
- 开发检查:标题比对先去空白、折全角、忽略大小写,并允许 H2–H4。只在归一化后确实没有该标题时判缺失。层级不一致记软警告,不扣分。不要把「待确认」或材料不足算进这道门禁。
|
||||
- 验证方式:`TestQualityGate_Validate_HeadingLevelAndSpaceDrift` 同时覆盖漂移通过和真实缺章失败。聊天触发须带 `AutoRepair`。
|
||||
- 适用边界:只覆盖 ATX 标题存在性。近义改名、章节被写进代码块、内容空洞仍不在本条范围内。
|
||||
- 防护落实:`internal/squad/quality_gate.go` 与 `quality_gate_test.go`。
|
||||
- 修订与失效:若产品要求章节层级必须与模板一致才可交付,应把软警告改回硬失败,并同步改回归用例。
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
lesson_id: LESSON-20260928-squad-commit-as-author
|
||||
lesson_state: validated
|
||||
owner: Cursor
|
||||
reviewer: Cursor(自审,dev 原例已复跑)
|
||||
last_reviewed: 2026-09-28
|
||||
reviewed_revision: b1ed8ecfe9fc5849288b6febf2bb4780319c8aca
|
||||
source_issues: [ISSUE-20260928-squad-commit-authority]
|
||||
keywords: [bizdev, docflow, dutyAuthorizer, AutoCommitUserID, OnBehalfOf, uow permission denied, 非编制人]
|
||||
---
|
||||
|
||||
# 小队账本自动提交要用编制人身份
|
||||
|
||||
- 触发条件:受控文档小队任务成功生成正文,但落盘报 `uow: permission denied` 或「版本账本/变更报告落盘失败」。
|
||||
- 机制与来源:`dutyAuthorizer` 对 `ActionCommit` 要求 principal 等于 `document_records.author_id`。触发者常常是其他项目成员。见 ISSUE-20260928-squad-commit-authority。
|
||||
- 开发检查:自动提交的 `AutoCommitUserID` 用文档编制人;实际触发用户写入 `OnBehalfOf`。不要为了小队路径放宽编制人校验。触发者或编制人为 0 时不要伪造代理身份。权限失败文案要写明「非编制人」,同时保留 `uow.ErrPermissionDenied` 哨兵。
|
||||
- 验证方式:非编制人触发应成功且快照 `actor_user_id` 为触发者,变更事件 `actor_user_id` 为编制人;编制人触发不设置 `OnBehalfOf`;非编制人直接 `ActionCommit` 仍拒绝。dev 原例 `run_1790559088975684237` 已 PASS,见测试报告 `2026-09-28-squad-commit-authority-test-report.md`。
|
||||
- 适用边界:只覆盖小队/agent 自动提交。人工编辑、批准、驳回仍按各自职责人校验。高风险候选仍要编制人确认。
|
||||
- 防护落实:单测在 `internal/bizdev/squad_commit_actor_test.go` 与 `TestDutyAuthorizerAllowsDocumentAuthorCommit`。dev 原例已用真实 pi-agent 重跑,见测试报告。没有新增 CI 门禁。
|
||||
- 修订与失效:若产品改为「非编制人不得触发生成」,本条应退役并改回触发者身份。
|
||||
@@ -0,0 +1,20 @@
|
||||
---
|
||||
lesson_id: LESSON-20260928-standard-role-reseed
|
||||
lesson_state: validated
|
||||
owner: Cursor
|
||||
reviewer: Cursor(自审)
|
||||
last_reviewed: 2026-09-28
|
||||
reviewed_revision: 4ba60c2c9d7eaf3e3e824475c0f3a44e10641190
|
||||
source_issues: [ISSUE-20260928-register-internal]
|
||||
keywords: [auth, register, role-guest, system_roles, is_system, 23503, 23505, INTERNAL]
|
||||
---
|
||||
|
||||
# 代码硬编码的标准角色必须可自愈且不可删
|
||||
|
||||
- 触发条件:注册、管理员建号或种子用户写入固定 `role_id`,而该角色只在历史 goose 种子里出现一次。
|
||||
- 机制与来源:`Register` 固定写 `role-guest`。00015 仅 `role-admin` 为 `is_system`。角色一旦被删,goose 不重跑、`BootstrapIAM` 只补用户,`user_role_bindings` 外键失败被脱敏成 INTERNAL。证据日期 2026-09-28,见 [任务](../short-term/2026-09-28-auth-register-internal.md)。
|
||||
- 开发检查:硬编码角色 id 须在迁移里 `ON CONFLICT DO UPDATE` 补种,并标 `is_system`。用户名一类唯一冲突返回领域错误,不要包进 `insert user:` 这类会被当成 500 的前缀。
|
||||
- 验证方式:缺角色的库补种后注册返回 200;重复用户名返回 400 且 `error` 为「用户名已存在」。
|
||||
- 适用边界:适用于 IAM 标准角色。业务自定义角色仍允许删除(无人引用时)。
|
||||
- 防护落实:migration 00077 + `DeleteRole` 既有系统角色拒绝。未新增 lint。
|
||||
- 修订与失效:若注册不再绑定 `role-guest`,本条对那个写入点失效,保留历史。
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user