@michelj/context-guard 0.4.1 → 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +74 -6
- package/README.zh-CN.md +74 -6
- package/{skills/context-guard/SKILL.md → SKILL.md} +216 -77
- package/bin/context-guard-skill.js +88 -3
- package/hooks.json +25 -1
- package/package.json +7 -3
- package/{skills/context-guard/references → references}/context-template.md +52 -1
- package/references/feature-chain-methodology.md +228 -0
- package/{skills/context-guard/scripts → scripts}/context_guard.py +3119 -121
- package/{skills/context-guard/scripts → scripts}/context_guard_hook.py +344 -12
- package/{skills/context-guard/tests → tests}/BC-20260701-090.sh +8 -7
- package/{skills/context-guard/tests → tests}/BC-20260702-096.sh +6 -3
- package/tests/BC-20260706-098.sh +66 -0
- package/tests/BC-20260707-099.sh +47 -0
- package/tests/BC-20260707-100.sh +46 -0
- package/tests/BC-20260707-101.sh +47 -0
- package/tests/BC-20260707-102.sh +68 -0
- package/tests/BC-20260707-103.sh +59 -0
- package/tests/BC-20260707-104.sh +103 -0
- package/tests/BC-20260707-105.sh +109 -0
- package/tests/BC-20260707-106.sh +80 -0
- package/tests/BC-20260707-107.sh +74 -0
- package/tests/BC-20260707-108.sh +48 -0
- package/tests/BC-20260707-109.sh +56 -0
- package/tests/BC-20260707-110.sh +71 -0
- package/tests/BC-20260707-111.sh +70 -0
- package/tests/BC-20260707-112.sh +45 -0
- package/tests/BC-20260707-113.sh +73 -0
- package/tests/BC-20260707-115.sh +77 -0
- package/tests/BC-20260707-116.sh +77 -0
- package/tests/BC-20260707-118.sh +115 -0
- package/tests/BC-20260707-119.sh +47 -0
- package/tests/BC-20260707-120.sh +60 -0
- package/tests/BC-20260707-121.sh +66 -0
- package/tests/BC-20260707-122.sh +48 -0
- package/tests/BC-20260707-123.sh +43 -0
- package/tests/BC-20260707-124.sh +56 -0
- package/tests/BC-20260707-125.sh +64 -0
- package/tests/BC-20260707-126.sh +80 -0
- package/tests/BC-20260707-127.sh +88 -0
- package/tests/BC-20260707-129.sh +59 -0
- package/tests/BC-20260707-130.sh +69 -0
- package/tests/BC-20260707-131.sh +140 -0
- package/tests/BC-20260707-132.sh +150 -0
- package/tests/BC-20260707-133.sh +70 -0
- package/tests/BC-20260708-136.sh +210 -0
- package/tests/BC-20260708-137.sh +106 -0
- package/tests/BC-20260708-138.sh +168 -0
- package/tests/BC-20260708-139.sh +79 -0
- package/tests/BC-20260709-002.sh +63 -0
- package/tests/BC-20260709-003.sh +239 -0
- package/tests/BC-20260709-006.sh +76 -0
- package/tests/BC-20260709-008.sh +168 -0
- package/tests/BC-20260710-001.sh +61 -0
- package/tests/BC-20260710-002.sh +111 -0
- package/tests/npm-install-smoke.sh +53 -0
- package/skills/context-guard/README.md +0 -234
- package/skills/context-guard/README.zh-CN.md +0 -234
- /package/{skills/context-guard/agents → agents}/openai.yaml +0 -0
- /package/{skills/context-guard/references → references}/register-template.md +0 -0
- /package/{skills/context-guard/references → references}/task-case-template.md +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260618-063.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260618-065.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260626-080.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260626-081.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260626-082.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260626-083.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260627-084.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260630-086.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260630-087.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260630-088.sh +0 -0
- /package/{skills/context-guard/tests → tests}/BC-20260630-089.sh +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-suggest-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
OUT="$ROOT/suggest.out"
|
|
8
|
+
|
|
9
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
ADD_OUTPUT="$(python3 "$SCRIPT" feature-chain-add \
|
|
12
|
+
--root "$ROOT" \
|
|
13
|
+
--title "Markdown 公式预览" \
|
|
14
|
+
--entry "用户输入 Markdown 公式" \
|
|
15
|
+
--exit-check "预览区显示 MathJax 渲染结果")"
|
|
16
|
+
CHAIN_ID="$(printf '%s\n' "$ADD_OUTPUT" | sed -n 's/.*feature chain: //p')"
|
|
17
|
+
|
|
18
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
19
|
+
--root "$ROOT" \
|
|
20
|
+
--chain-id "$CHAIN_ID" \
|
|
21
|
+
--node-title "MathJax 渲染完成" \
|
|
22
|
+
--bad-case "BC-20260707-100" \
|
|
23
|
+
--check "预览区包含渲染后的公式且没有空白" >/dev/null
|
|
24
|
+
|
|
25
|
+
python3 "$SCRIPT" feature-chain-add \
|
|
26
|
+
--root "$ROOT" \
|
|
27
|
+
--title "GPU 监控按钮" \
|
|
28
|
+
--entry "点击 GPU 监控按钮" \
|
|
29
|
+
--exit-check "打开包含 grafana_url 的监控页" >/dev/null
|
|
30
|
+
|
|
31
|
+
python3 "$SCRIPT" feature-chain-suggest \
|
|
32
|
+
--root "$ROOT" \
|
|
33
|
+
--query "Markdown 数学公式预览 MathJax 渲染空白" >"$OUT"
|
|
34
|
+
grep -q "Markdown 公式预览" "$OUT"
|
|
35
|
+
grep -q "MathJax 渲染完成" "$OUT"
|
|
36
|
+
grep -q "next: attach the bad case to a candidate checkpoint" "$OUT"
|
|
37
|
+
if grep -q "GPU 监控按钮" "$OUT"; then
|
|
38
|
+
cat "$OUT"
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
python3 "$SCRIPT" feature-chain-suggest \
|
|
43
|
+
--root "$ROOT" \
|
|
44
|
+
--query "worker lease keepalive 释放失败" >"$OUT"
|
|
45
|
+
grep -q "feature-chain candidates: none" "$OUT"
|
|
46
|
+
grep -q "proposal-needed" "$OUT"
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-proposed-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
OUT="$ROOT/out.txt"
|
|
8
|
+
|
|
9
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
ADD_OUTPUT="$(python3 "$SCRIPT" feature-chain-add \
|
|
12
|
+
--root "$ROOT" \
|
|
13
|
+
--title "Markdown 公式预览" \
|
|
14
|
+
--entry "用户输入 Markdown 公式" \
|
|
15
|
+
--exit-check "预览区显示 MathJax 渲染结果" \
|
|
16
|
+
--command-text "printf 'should not run unless approved\n'")"
|
|
17
|
+
CHAIN_ID="$(printf '%s\n' "$ADD_OUTPUT" | sed -n 's/.*feature chain: //p')"
|
|
18
|
+
|
|
19
|
+
python3 - "$ROOT/.codex/context/test-hub/feature-chains.json" "$CHAIN_ID" <<'PY'
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
import json
|
|
22
|
+
import sys
|
|
23
|
+
|
|
24
|
+
registry = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
|
25
|
+
chain = next(item for item in registry["chains"] if item["id"] == sys.argv[2])
|
|
26
|
+
assert chain["status"] == "proposed", chain
|
|
27
|
+
assert chain["source"] == "feature-chain", chain
|
|
28
|
+
PY
|
|
29
|
+
|
|
30
|
+
python3 "$SCRIPT" dev-complete --root "$ROOT" >"$OUT"
|
|
31
|
+
grep -q "no approved every-dev-completion tests" "$OUT"
|
|
32
|
+
|
|
33
|
+
python3 "$SCRIPT" test-hub-add \
|
|
34
|
+
--root "$ROOT" \
|
|
35
|
+
--title "Context 初始化冒烟测试" \
|
|
36
|
+
--command-text "printf 'ok\n'" >/dev/null
|
|
37
|
+
|
|
38
|
+
python3 - "$ROOT/.codex/context/test-hub/registry.json" <<'PY'
|
|
39
|
+
from pathlib import Path
|
|
40
|
+
import json
|
|
41
|
+
import sys
|
|
42
|
+
|
|
43
|
+
registry = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
|
44
|
+
test = registry["tests"][0]
|
|
45
|
+
assert test["status"] == "approved", test
|
|
46
|
+
assert test["run_policy"] == "every-dev-completion", test
|
|
47
|
+
PY
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-approve-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
OUT="$ROOT/out.txt"
|
|
8
|
+
|
|
9
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
10
|
+
ADD_OUTPUT="$(python3 "$SCRIPT" feature-chain-add \
|
|
11
|
+
--root "$ROOT" \
|
|
12
|
+
--title "Markdown 公式预览" \
|
|
13
|
+
--entry "用户输入 Markdown 公式" \
|
|
14
|
+
--exit-check "预览区显示 MathJax 渲染结果")"
|
|
15
|
+
CHAIN_ID="$(printf '%s\n' "$ADD_OUTPUT" | sed -n 's/.*feature chain: //p')"
|
|
16
|
+
|
|
17
|
+
if python3 "$SCRIPT" feature-chain-approve \
|
|
18
|
+
--root "$ROOT" \
|
|
19
|
+
--chain-id "$CHAIN_ID" \
|
|
20
|
+
--command-text "printf 'ok\n'" >"$OUT" 2>&1; then
|
|
21
|
+
cat "$OUT"
|
|
22
|
+
exit 1
|
|
23
|
+
fi
|
|
24
|
+
grep -q "requires at least one checkpoint" "$OUT"
|
|
25
|
+
|
|
26
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
27
|
+
--root "$ROOT" \
|
|
28
|
+
--chain-id "$CHAIN_ID" \
|
|
29
|
+
--node-title "MathJax 渲染完成" \
|
|
30
|
+
--bad-case "BC-20260707-102" \
|
|
31
|
+
--check "预览区包含渲染后的公式且没有空白" >/dev/null
|
|
32
|
+
|
|
33
|
+
if python3 "$SCRIPT" feature-chain-approve \
|
|
34
|
+
--root "$ROOT" \
|
|
35
|
+
--chain-id "$CHAIN_ID" >"$OUT" 2>&1; then
|
|
36
|
+
cat "$OUT"
|
|
37
|
+
exit 1
|
|
38
|
+
fi
|
|
39
|
+
grep -q "requires --command-text" "$OUT"
|
|
40
|
+
|
|
41
|
+
python3 "$SCRIPT" feature-chain-approve \
|
|
42
|
+
--root "$ROOT" \
|
|
43
|
+
--chain-id "$CHAIN_ID" \
|
|
44
|
+
--command-text "printf 'CG_CHECKPOINT:MathJax 渲染完成:PASS\n'" >"$OUT"
|
|
45
|
+
grep -q "feature chain approved" "$OUT"
|
|
46
|
+
|
|
47
|
+
python3 - "$ROOT/.codex/context/test-hub/feature-chains.json" "$CHAIN_ID" <<'PY'
|
|
48
|
+
from pathlib import Path
|
|
49
|
+
import json
|
|
50
|
+
import sys
|
|
51
|
+
|
|
52
|
+
chain = next(
|
|
53
|
+
item
|
|
54
|
+
for item in json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))["chains"]
|
|
55
|
+
if item["id"] == sys.argv[2]
|
|
56
|
+
)
|
|
57
|
+
assert chain["status"] == "approved"
|
|
58
|
+
assert chain["run_policy"] == "every-dev-completion"
|
|
59
|
+
assert chain["type"] == "command"
|
|
60
|
+
assert "CG_CHECKPOINT:MathJax 渲染完成:PASS" in chain["command"]
|
|
61
|
+
PY
|
|
62
|
+
|
|
63
|
+
python3 "$SCRIPT" validate-feature-chains --root "$ROOT" >"$OUT"
|
|
64
|
+
grep -q "feature-chain validation passed: 1 chain(s), 0 warning(s)" "$OUT"
|
|
65
|
+
|
|
66
|
+
python3 "$SCRIPT" dev-complete --root "$ROOT" >"$OUT"
|
|
67
|
+
grep -q "1 passed, 0 failed, 0 blocked" "$OUT"
|
|
68
|
+
grep -q "success artifacts cleaned" "$OUT"
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-policy-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
OUT="$ROOT/out.txt"
|
|
8
|
+
|
|
9
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
10
|
+
ADD_OUTPUT="$(python3 "$SCRIPT" feature-chain-add \
|
|
11
|
+
--root "$ROOT" \
|
|
12
|
+
--title "GPU 监控按钮" \
|
|
13
|
+
--entry "点击 GPU 监控按钮" \
|
|
14
|
+
--exit-check "打开包含有效 grafana_url 的监控页")"
|
|
15
|
+
CHAIN_ID="$(printf '%s\n' "$ADD_OUTPUT" | sed -n 's/.*feature chain: //p')"
|
|
16
|
+
|
|
17
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
18
|
+
--root "$ROOT" \
|
|
19
|
+
--chain-id "$CHAIN_ID" \
|
|
20
|
+
--node-title "后端返回监控 URL" \
|
|
21
|
+
--bad-case "BC-20260707-103" \
|
|
22
|
+
--check "grafana_url 不为空" >/dev/null
|
|
23
|
+
|
|
24
|
+
python3 "$SCRIPT" feature-chain-approve \
|
|
25
|
+
--root "$ROOT" \
|
|
26
|
+
--chain-id "$CHAIN_ID" \
|
|
27
|
+
--command-text "printf 'CG_CHECKPOINT:后端返回监控 URL:PASS\n'" >/dev/null
|
|
28
|
+
|
|
29
|
+
python3 "$SCRIPT" dev-complete --root "$ROOT" >"$OUT"
|
|
30
|
+
grep -q "1 passed, 0 failed, 0 blocked" "$OUT"
|
|
31
|
+
|
|
32
|
+
python3 "$SCRIPT" feature-chain-set-policy \
|
|
33
|
+
--root "$ROOT" \
|
|
34
|
+
--chain-id "$CHAIN_ID" \
|
|
35
|
+
--run-policy "relevant-only" \
|
|
36
|
+
--reason "用户要求只在修改 GPU 监控流程时运行" >"$OUT"
|
|
37
|
+
grep -q "feature chain policy updated" "$OUT"
|
|
38
|
+
|
|
39
|
+
python3 - "$ROOT/.codex/context/test-hub/feature-chains.json" "$CHAIN_ID" <<'PY'
|
|
40
|
+
from pathlib import Path
|
|
41
|
+
import json
|
|
42
|
+
import sys
|
|
43
|
+
|
|
44
|
+
chain = next(
|
|
45
|
+
item
|
|
46
|
+
for item in json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))["chains"]
|
|
47
|
+
if item["id"] == sys.argv[2]
|
|
48
|
+
)
|
|
49
|
+
assert chain["status"] == "approved"
|
|
50
|
+
assert chain["run_policy"] == "relevant-only"
|
|
51
|
+
assert "GPU 监控" in chain["policy_reason"]
|
|
52
|
+
PY
|
|
53
|
+
|
|
54
|
+
python3 "$SCRIPT" dev-complete --root "$ROOT" >"$OUT"
|
|
55
|
+
grep -q "no approved every-dev-completion tests" "$OUT"
|
|
56
|
+
if grep -q "后端返回监控 URL" "$OUT"; then
|
|
57
|
+
cat "$OUT"
|
|
58
|
+
exit 1
|
|
59
|
+
fi
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py"
|
|
5
|
+
ROOT_FAIL="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-checkpoint-fail-XXXXXX")"
|
|
6
|
+
ROOT_PASS="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-checkpoint-pass-XXXXXX")"
|
|
7
|
+
trap 'rm -rf "$ROOT_FAIL" "$ROOT_PASS"' EXIT
|
|
8
|
+
OUT="$ROOT_FAIL/out.txt"
|
|
9
|
+
|
|
10
|
+
python3 "$SCRIPT" init --root "$ROOT_FAIL" >/dev/null
|
|
11
|
+
ADD_OUTPUT="$(python3 "$SCRIPT" feature-chain-add \
|
|
12
|
+
--root "$ROOT_FAIL" \
|
|
13
|
+
--title "GPU 监控按钮" \
|
|
14
|
+
--entry "点击 GPU 监控按钮" \
|
|
15
|
+
--exit-check "打开包含有效 grafana_url 的监控页")"
|
|
16
|
+
CHAIN_ID="$(printf '%s\n' "$ADD_OUTPUT" | sed -n 's/.*feature chain: //p')"
|
|
17
|
+
|
|
18
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
19
|
+
--root "$ROOT_FAIL" \
|
|
20
|
+
--chain-id "$CHAIN_ID" \
|
|
21
|
+
--node-title "后端返回监控 URL" \
|
|
22
|
+
--bad-case "BC-20260707-104" \
|
|
23
|
+
--check "grafana_url 不为空" >/dev/null
|
|
24
|
+
|
|
25
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
26
|
+
--root "$ROOT_FAIL" \
|
|
27
|
+
--chain-id "$CHAIN_ID" \
|
|
28
|
+
--node-title "前端打开监控页" \
|
|
29
|
+
--bad-case "BC-20260707-104" \
|
|
30
|
+
--check "点击后进入监控页" >/dev/null
|
|
31
|
+
|
|
32
|
+
python3 - "$ROOT_FAIL/.codex/context/test-hub/feature-chains.json" "$CHAIN_ID" <<'PY'
|
|
33
|
+
from pathlib import Path
|
|
34
|
+
import json
|
|
35
|
+
import sys
|
|
36
|
+
path = Path(sys.argv[1])
|
|
37
|
+
chain_id = sys.argv[2]
|
|
38
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
39
|
+
chain = next(item for item in data["chains"] if item["id"] == chain_id)
|
|
40
|
+
chain["status"] = "approved"
|
|
41
|
+
chain["type"] = "command"
|
|
42
|
+
chain["command"] = "printf 'CG_CHECKPOINT:后端返回监控 URL:PASS\\nCG_CHECKPOINT:前端打开监控页:FAIL:缺少 grafana_url\\n'"
|
|
43
|
+
path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
44
|
+
PY
|
|
45
|
+
|
|
46
|
+
if python3 "$SCRIPT" dev-complete --root "$ROOT_FAIL" >"$OUT" 2>&1; then
|
|
47
|
+
cat "$OUT"
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
grep -q "checkpoint failed: 前端打开监控页 - 缺少 grafana_url" "$OUT"
|
|
51
|
+
|
|
52
|
+
python3 - "$ROOT_FAIL/.codex/context/test-hub/last-run.json" <<'PY'
|
|
53
|
+
from pathlib import Path
|
|
54
|
+
import json
|
|
55
|
+
import sys
|
|
56
|
+
|
|
57
|
+
run = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
|
58
|
+
result = run["results"][0]
|
|
59
|
+
assert result["status"] == "failed"
|
|
60
|
+
assert result["reason"] == "checkpoint failed: 前端打开监控页 - 缺少 grafana_url"
|
|
61
|
+
assert [item["status"] for item in result["checkpoints"]] == ["pass", "fail"]
|
|
62
|
+
PY
|
|
63
|
+
|
|
64
|
+
OUT="$ROOT_PASS/out.txt"
|
|
65
|
+
python3 "$SCRIPT" init --root "$ROOT_PASS" >/dev/null
|
|
66
|
+
ADD_OUTPUT="$(python3 "$SCRIPT" feature-chain-add \
|
|
67
|
+
--root "$ROOT_PASS" \
|
|
68
|
+
--title "GPU 监控按钮" \
|
|
69
|
+
--entry "点击 GPU 监控按钮" \
|
|
70
|
+
--exit-check "打开包含有效 grafana_url 的监控页")"
|
|
71
|
+
CHAIN_ID="$(printf '%s\n' "$ADD_OUTPUT" | sed -n 's/.*feature chain: //p')"
|
|
72
|
+
|
|
73
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
74
|
+
--root "$ROOT_PASS" \
|
|
75
|
+
--chain-id "$CHAIN_ID" \
|
|
76
|
+
--node-title "后端返回监控 URL" \
|
|
77
|
+
--bad-case "BC-20260707-104" \
|
|
78
|
+
--check "grafana_url 不为空" >/dev/null
|
|
79
|
+
|
|
80
|
+
python3 "$SCRIPT" feature-chain-approve \
|
|
81
|
+
--root "$ROOT_PASS" \
|
|
82
|
+
--chain-id "$CHAIN_ID" \
|
|
83
|
+
--command-text "printf 'CG_CHECKPOINT:后端返回监控 URL:PASS\n'" >/dev/null
|
|
84
|
+
|
|
85
|
+
python3 "$SCRIPT" dev-complete --root "$ROOT_PASS" >"$OUT"
|
|
86
|
+
grep -q "1 passed, 0 failed, 0 blocked" "$OUT"
|
|
87
|
+
grep -q "success artifacts cleaned" "$OUT"
|
|
88
|
+
|
|
89
|
+
if find "$ROOT_PASS/.codex/context/test-hub/runs" -mindepth 1 -maxdepth 1 2>/dev/null | grep -q .; then
|
|
90
|
+
find "$ROOT_PASS/.codex/context/test-hub/runs" -mindepth 1 -maxdepth 1
|
|
91
|
+
exit 1
|
|
92
|
+
fi
|
|
93
|
+
|
|
94
|
+
python3 - "$ROOT_PASS/.codex/context/test-hub/last-run.json" <<'PY'
|
|
95
|
+
from pathlib import Path
|
|
96
|
+
import json
|
|
97
|
+
import sys
|
|
98
|
+
|
|
99
|
+
run = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
|
|
100
|
+
result = run["results"][0]
|
|
101
|
+
assert result["status"] == "passed"
|
|
102
|
+
assert result["checkpoints"][0]["label"] == "后端返回监控 URL"
|
|
103
|
+
PY
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py"
|
|
5
|
+
ROOT_BAD="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-marker-bad-XXXXXX")"
|
|
6
|
+
ROOT_GOOD="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-marker-good-XXXXXX")"
|
|
7
|
+
trap 'rm -rf "$ROOT_BAD" "$ROOT_GOOD"' EXIT
|
|
8
|
+
OUT="$ROOT_BAD/out.txt"
|
|
9
|
+
|
|
10
|
+
create_chain() {
|
|
11
|
+
local root="$1"
|
|
12
|
+
local mode="${2:-proposed}"
|
|
13
|
+
local command_text="${3:-}"
|
|
14
|
+
python3 "$SCRIPT" init --root "$root" >/dev/null
|
|
15
|
+
local add_output
|
|
16
|
+
add_output="$(python3 "$SCRIPT" feature-chain-add \
|
|
17
|
+
--root "$root" \
|
|
18
|
+
--title "GPU 监控按钮" \
|
|
19
|
+
--entry "点击 GPU 监控按钮" \
|
|
20
|
+
--exit-check "打开包含有效 grafana_url 的监控页")"
|
|
21
|
+
local chain_id
|
|
22
|
+
chain_id="$(printf '%s\n' "$add_output" | sed -n 's/.*feature chain: //p')"
|
|
23
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
24
|
+
--root "$root" \
|
|
25
|
+
--chain-id "$chain_id" \
|
|
26
|
+
--node-title "后端返回监控 URL" \
|
|
27
|
+
--bad-case "BC-20260707-105" \
|
|
28
|
+
--check "grafana_url 不为空" >/dev/null
|
|
29
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
30
|
+
--root "$root" \
|
|
31
|
+
--chain-id "$chain_id" \
|
|
32
|
+
--node-title "前端打开监控页" \
|
|
33
|
+
--bad-case "BC-20260707-105" \
|
|
34
|
+
--check "点击后进入监控页" >/dev/null
|
|
35
|
+
if [[ "$mode" == "direct-approved" ]]; then
|
|
36
|
+
python3 - "$root/.codex/context/test-hub/feature-chains.json" "$chain_id" "$command_text" <<'PY'
|
|
37
|
+
from pathlib import Path
|
|
38
|
+
import json
|
|
39
|
+
import sys
|
|
40
|
+
path = Path(sys.argv[1])
|
|
41
|
+
chain_id = sys.argv[2]
|
|
42
|
+
command = sys.argv[3]
|
|
43
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
44
|
+
chain = next(item for item in data["chains"] if item["id"] == chain_id)
|
|
45
|
+
chain["status"] = "approved"
|
|
46
|
+
chain["type"] = "command"
|
|
47
|
+
chain["command"] = command
|
|
48
|
+
path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
49
|
+
PY
|
|
50
|
+
fi
|
|
51
|
+
printf '%s' "$chain_id"
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
CHAIN_ID="$(create_chain "$ROOT_BAD" direct-approved "printf 'CG_CHECKPOINT:未登记检查点:PASS\n'")"
|
|
55
|
+
python3 - "$ROOT_BAD/.codex/context/test-hub/feature-chains.json" "$CHAIN_ID" <<'PY'
|
|
56
|
+
from pathlib import Path
|
|
57
|
+
import json
|
|
58
|
+
import sys
|
|
59
|
+
|
|
60
|
+
chain = next(
|
|
61
|
+
item
|
|
62
|
+
for item in json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))["chains"]
|
|
63
|
+
if item["id"] == sys.argv[2]
|
|
64
|
+
)
|
|
65
|
+
nodes = chain["nodes"]
|
|
66
|
+
assert len(nodes) == 2, nodes
|
|
67
|
+
ids = [node["id"] for node in nodes]
|
|
68
|
+
assert len(set(ids)) == 2, ids
|
|
69
|
+
assert "test" not in ids, ids
|
|
70
|
+
PY
|
|
71
|
+
|
|
72
|
+
if python3 "$SCRIPT" dev-complete --root "$ROOT_BAD" >"$OUT" 2>&1; then
|
|
73
|
+
cat "$OUT"
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
grep -q "unknown checkpoint marker: 未登记检查点" "$OUT"
|
|
77
|
+
|
|
78
|
+
python3 - "$ROOT_BAD/.codex/context/test-hub/last-run.json" <<'PY'
|
|
79
|
+
from pathlib import Path
|
|
80
|
+
import json
|
|
81
|
+
import sys
|
|
82
|
+
|
|
83
|
+
result = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))["results"][0]
|
|
84
|
+
assert result["status"] == "failed"
|
|
85
|
+
assert result["reason"] == "unknown checkpoint marker: 未登记检查点"
|
|
86
|
+
assert result["checkpoints"][0]["known"] is False
|
|
87
|
+
PY
|
|
88
|
+
|
|
89
|
+
OUT="$ROOT_GOOD/out.txt"
|
|
90
|
+
CHAIN_ID="$(create_chain "$ROOT_GOOD")"
|
|
91
|
+
python3 "$SCRIPT" feature-chain-approve \
|
|
92
|
+
--root "$ROOT_GOOD" \
|
|
93
|
+
--chain-id "$CHAIN_ID" \
|
|
94
|
+
--command-text "printf 'CG_CHECKPOINT:后端返回监控 URL:PASS\nCG_CHECKPOINT:前端打开监控页:PASS\n'" >/dev/null
|
|
95
|
+
|
|
96
|
+
python3 "$SCRIPT" dev-complete --root "$ROOT_GOOD" >"$OUT"
|
|
97
|
+
grep -q "1 passed, 0 failed, 0 blocked" "$OUT"
|
|
98
|
+
grep -q "success artifacts cleaned" "$OUT"
|
|
99
|
+
|
|
100
|
+
python3 - "$ROOT_GOOD/.codex/context/test-hub/last-run.json" <<'PY'
|
|
101
|
+
from pathlib import Path
|
|
102
|
+
import json
|
|
103
|
+
import sys
|
|
104
|
+
|
|
105
|
+
result = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))["results"][0]
|
|
106
|
+
assert result["status"] == "passed"
|
|
107
|
+
assert [item["known"] for item in result["checkpoints"]] == [True, True]
|
|
108
|
+
assert [item["label"] for item in result["checkpoints"]] == ["后端返回监控 URL", "前端打开监控页"]
|
|
109
|
+
PY
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-missing-checkpoint-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
OUT="$ROOT/out.txt"
|
|
8
|
+
|
|
9
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
10
|
+
ADD_OUTPUT="$(python3 "$SCRIPT" feature-chain-add \
|
|
11
|
+
--root "$ROOT" \
|
|
12
|
+
--title "GPU 监控按钮" \
|
|
13
|
+
--entry "点击 GPU 监控按钮" \
|
|
14
|
+
--exit-check "打开包含有效 grafana_url 的监控页")"
|
|
15
|
+
CHAIN_ID="$(printf '%s\n' "$ADD_OUTPUT" | sed -n 's/.*feature chain: //p')"
|
|
16
|
+
|
|
17
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
18
|
+
--root "$ROOT" \
|
|
19
|
+
--chain-id "$CHAIN_ID" \
|
|
20
|
+
--node-title "后端返回监控 URL" \
|
|
21
|
+
--bad-case "BC-20260707-106" \
|
|
22
|
+
--check "grafana_url 不为空" >/dev/null
|
|
23
|
+
|
|
24
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
25
|
+
--root "$ROOT" \
|
|
26
|
+
--chain-id "$CHAIN_ID" \
|
|
27
|
+
--node-title "前端打开监控页" \
|
|
28
|
+
--bad-case "BC-20260707-106" \
|
|
29
|
+
--check "点击后进入监控页" >/dev/null
|
|
30
|
+
|
|
31
|
+
python3 - "$ROOT/.codex/context/test-hub/feature-chains.json" "$CHAIN_ID" <<'PY'
|
|
32
|
+
from pathlib import Path
|
|
33
|
+
import json
|
|
34
|
+
import sys
|
|
35
|
+
path = Path(sys.argv[1])
|
|
36
|
+
chain_id = sys.argv[2]
|
|
37
|
+
data = json.loads(path.read_text(encoding="utf-8"))
|
|
38
|
+
chain = next(item for item in data["chains"] if item["id"] == chain_id)
|
|
39
|
+
chain["status"] = "approved"
|
|
40
|
+
chain["type"] = "command"
|
|
41
|
+
chain["command"] = "printf 'CG_CHECKPOINT:后端返回监控 URL:PASS\\n'"
|
|
42
|
+
path.write_text(json.dumps(data, ensure_ascii=False, indent=2) + "\n", encoding="utf-8")
|
|
43
|
+
PY
|
|
44
|
+
|
|
45
|
+
if python3 "$SCRIPT" dev-complete --root "$ROOT" >"$OUT" 2>&1; then
|
|
46
|
+
cat "$OUT"
|
|
47
|
+
exit 1
|
|
48
|
+
fi
|
|
49
|
+
grep -q "missing checkpoint marker: 前端打开监控页" "$OUT"
|
|
50
|
+
|
|
51
|
+
python3 - "$ROOT/.codex/context/test-hub/last-run.json" <<'PY'
|
|
52
|
+
from pathlib import Path
|
|
53
|
+
import json
|
|
54
|
+
import sys
|
|
55
|
+
|
|
56
|
+
result = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))["results"][0]
|
|
57
|
+
assert result["status"] == "failed"
|
|
58
|
+
assert result["reason"] == "missing checkpoint marker: 前端打开监控页"
|
|
59
|
+
assert [item["label"] for item in result["missing_checkpoints"]] == ["前端打开监控页"]
|
|
60
|
+
PY
|
|
61
|
+
|
|
62
|
+
python3 "$SCRIPT" feature-chain-approve \
|
|
63
|
+
--root "$ROOT" \
|
|
64
|
+
--chain-id "$CHAIN_ID" \
|
|
65
|
+
--command-text "printf 'CG_CHECKPOINT:后端返回监控 URL:PASS\nCG_CHECKPOINT:前端打开监控页:PASS\n'" >/dev/null
|
|
66
|
+
|
|
67
|
+
python3 "$SCRIPT" dev-complete --root "$ROOT" >"$OUT"
|
|
68
|
+
grep -q "1 passed, 0 failed, 0 blocked" "$OUT"
|
|
69
|
+
grep -q "success artifacts cleaned" "$OUT"
|
|
70
|
+
|
|
71
|
+
python3 - "$ROOT/.codex/context/test-hub/last-run.json" <<'PY'
|
|
72
|
+
from pathlib import Path
|
|
73
|
+
import json
|
|
74
|
+
import sys
|
|
75
|
+
|
|
76
|
+
result = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))["results"][0]
|
|
77
|
+
assert result["status"] == "passed"
|
|
78
|
+
assert [item["label"] for item in result["checkpoints"]] == ["后端返回监控 URL", "前端打开监控页"]
|
|
79
|
+
assert result["missing_checkpoints"] == []
|
|
80
|
+
PY
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-checkpoint-policy-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
OUT="$ROOT/out.txt"
|
|
8
|
+
|
|
9
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
10
|
+
ADD_OUTPUT="$(python3 "$SCRIPT" feature-chain-add \
|
|
11
|
+
--root "$ROOT" \
|
|
12
|
+
--title "GPU 监控按钮" \
|
|
13
|
+
--entry "点击 GPU 监控按钮" \
|
|
14
|
+
--exit-check "打开包含有效 grafana_url 的监控页")"
|
|
15
|
+
CHAIN_ID="$(printf '%s\n' "$ADD_OUTPUT" | sed -n 's/.*feature chain: //p')"
|
|
16
|
+
|
|
17
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
18
|
+
--root "$ROOT" \
|
|
19
|
+
--chain-id "$CHAIN_ID" \
|
|
20
|
+
--node-title "后端返回监控 URL" \
|
|
21
|
+
--bad-case "BC-20260707-107" \
|
|
22
|
+
--check "grafana_url 不为空" >/dev/null
|
|
23
|
+
|
|
24
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
25
|
+
--root "$ROOT" \
|
|
26
|
+
--chain-id "$CHAIN_ID" \
|
|
27
|
+
--node-title "前端打开监控页" \
|
|
28
|
+
--bad-case "BC-20260707-107" \
|
|
29
|
+
--check "点击后进入监控页" >/dev/null
|
|
30
|
+
|
|
31
|
+
python3 "$SCRIPT" feature-chain-set-checkpoint \
|
|
32
|
+
--root "$ROOT" \
|
|
33
|
+
--chain-id "$CHAIN_ID" \
|
|
34
|
+
--node-title "前端打开监控页" \
|
|
35
|
+
--required optional \
|
|
36
|
+
--reason "浏览器环境才运行" >/dev/null
|
|
37
|
+
|
|
38
|
+
python3 "$SCRIPT" feature-chain-approve \
|
|
39
|
+
--root "$ROOT" \
|
|
40
|
+
--chain-id "$CHAIN_ID" \
|
|
41
|
+
--command-text "printf 'CG_CHECKPOINT:后端返回监控 URL:PASS\n'" >/dev/null
|
|
42
|
+
|
|
43
|
+
python3 "$SCRIPT" validate-feature-chains --root "$ROOT" >"$OUT"
|
|
44
|
+
grep -q "feature-chain validation passed" "$OUT"
|
|
45
|
+
|
|
46
|
+
python3 "$SCRIPT" dev-complete --root "$ROOT" >"$OUT"
|
|
47
|
+
grep -q "1 passed, 0 failed, 0 blocked" "$OUT"
|
|
48
|
+
grep -q "success artifacts cleaned" "$OUT"
|
|
49
|
+
|
|
50
|
+
python3 - "$ROOT/.codex/context/test-hub/feature-chains.json" <<'PY'
|
|
51
|
+
from pathlib import Path
|
|
52
|
+
import json
|
|
53
|
+
import sys
|
|
54
|
+
|
|
55
|
+
chain = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))["chains"][0]
|
|
56
|
+
nodes = {node["title"]: node for node in chain["nodes"]}
|
|
57
|
+
optional = nodes["前端打开监控页"]
|
|
58
|
+
assert optional["required"] is False
|
|
59
|
+
assert optional["optional"] is True
|
|
60
|
+
assert optional["optional_reason"] == "浏览器环境才运行"
|
|
61
|
+
PY
|
|
62
|
+
|
|
63
|
+
python3 "$SCRIPT" feature-chain-set-checkpoint \
|
|
64
|
+
--root "$ROOT" \
|
|
65
|
+
--chain-id "$CHAIN_ID" \
|
|
66
|
+
--node-title "前端打开监控页" \
|
|
67
|
+
--required required \
|
|
68
|
+
--reason "用户要求恢复每次运行" >/dev/null
|
|
69
|
+
|
|
70
|
+
if python3 "$SCRIPT" dev-complete --root "$ROOT" >"$OUT" 2>&1; then
|
|
71
|
+
cat "$OUT"
|
|
72
|
+
exit 1
|
|
73
|
+
fi
|
|
74
|
+
grep -q "missing checkpoint marker: 前端打开监控页" "$OUT"
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-feature-chain-list-policy-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
OUT="$ROOT/out.txt"
|
|
8
|
+
|
|
9
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
10
|
+
ADD_OUTPUT="$(python3 "$SCRIPT" feature-chain-add \
|
|
11
|
+
--root "$ROOT" \
|
|
12
|
+
--title "GPU 监控按钮" \
|
|
13
|
+
--entry "点击 GPU 监控按钮" \
|
|
14
|
+
--exit-check "打开包含有效 grafana_url 的监控页")"
|
|
15
|
+
CHAIN_ID="$(printf '%s\n' "$ADD_OUTPUT" | sed -n 's/.*feature chain: //p')"
|
|
16
|
+
|
|
17
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
18
|
+
--root "$ROOT" \
|
|
19
|
+
--chain-id "$CHAIN_ID" \
|
|
20
|
+
--node-title "后端返回监控 URL" \
|
|
21
|
+
--bad-case "BC-20260707-108" \
|
|
22
|
+
--check "grafana_url 不为空" >/dev/null
|
|
23
|
+
|
|
24
|
+
python3 "$SCRIPT" feature-chain-attach-bc \
|
|
25
|
+
--root "$ROOT" \
|
|
26
|
+
--chain-id "$CHAIN_ID" \
|
|
27
|
+
--node-title "前端打开监控页" \
|
|
28
|
+
--bad-case "BC-20260707-108" \
|
|
29
|
+
--check "点击后进入监控页" >/dev/null
|
|
30
|
+
|
|
31
|
+
python3 "$SCRIPT" feature-chain-set-checkpoint \
|
|
32
|
+
--root "$ROOT" \
|
|
33
|
+
--chain-id "$CHAIN_ID" \
|
|
34
|
+
--node-title "前端打开监控页" \
|
|
35
|
+
--required optional \
|
|
36
|
+
--reason "浏览器环境才运行" >/dev/null
|
|
37
|
+
|
|
38
|
+
python3 "$SCRIPT" feature-chain-list --root "$ROOT" >"$OUT"
|
|
39
|
+
grep -q "2 node(s), 1 required, 1 optional" "$OUT"
|
|
40
|
+
if grep -q "checkpoint:" "$OUT"; then
|
|
41
|
+
cat "$OUT"
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
python3 "$SCRIPT" feature-chain-list --root "$ROOT" --verbose >"$OUT"
|
|
46
|
+
grep -q "2 node(s), 1 required, 1 optional" "$OUT"
|
|
47
|
+
grep -q "checkpoint: 后端返回监控 URL | required" "$OUT"
|
|
48
|
+
grep -q "checkpoint: 前端打开监控页 | optional | reason: 浏览器环境才运行" "$OUT"
|