@michelj/context-guard 0.4.0
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 +203 -0
- package/README.zh-CN.md +203 -0
- package/bin/context-guard-skill.js +185 -0
- package/hooks.json +41 -0
- package/package.json +30 -0
- package/skills/context-guard/README.md +203 -0
- package/skills/context-guard/README.zh-CN.md +203 -0
- package/skills/context-guard/SKILL.md +519 -0
- package/skills/context-guard/agents/openai.yaml +4 -0
- package/skills/context-guard/references/context-template.md +290 -0
- package/skills/context-guard/references/register-template.md +85 -0
- package/skills/context-guard/references/task-case-template.md +63 -0
- package/skills/context-guard/scripts/context_guard.py +4661 -0
- package/skills/context-guard/scripts/context_guard_hook.py +465 -0
- package/skills/context-guard/tests/BC-20260618-063.sh +116 -0
- package/skills/context-guard/tests/BC-20260618-065.sh +66 -0
- package/skills/context-guard/tests/BC-20260626-080.sh +48 -0
- package/skills/context-guard/tests/BC-20260626-081.sh +40 -0
- package/skills/context-guard/tests/BC-20260626-082.sh +32 -0
- package/skills/context-guard/tests/BC-20260626-083.sh +66 -0
- package/skills/context-guard/tests/BC-20260627-084.sh +74 -0
- package/skills/context-guard/tests/BC-20260630-086.sh +50 -0
- package/skills/context-guard/tests/BC-20260630-087.sh +103 -0
- package/skills/context-guard/tests/BC-20260630-088.sh +32 -0
- package/skills/context-guard/tests/BC-20260630-089.sh +63 -0
- package/skills/context-guard/tests/BC-20260701-090.sh +83 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py}"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-hidden-details-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
|
|
8
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
9
|
+
python3 "$SCRIPT" set-language --language zh --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
CTX="$ROOT/.codex/context"
|
|
12
|
+
cat > "$CTX/roadmap.md" <<'MD'
|
|
13
|
+
# Context Roadmap
|
|
14
|
+
|
|
15
|
+
## Nodes
|
|
16
|
+
|
|
17
|
+
### NODE-20260626-001: 可点击路线节点
|
|
18
|
+
|
|
19
|
+
- Date: 2026-06-26
|
|
20
|
+
- Status: done
|
|
21
|
+
- Level: major
|
|
22
|
+
- Branch: Main
|
|
23
|
+
- Parent: none
|
|
24
|
+
- Outcome: 这个节点的详细概括只能在点击节点后显示,不能默认铺在 roadmap 下方。
|
|
25
|
+
- Next: none
|
|
26
|
+
- Linked bad cases: none
|
|
27
|
+
MD
|
|
28
|
+
|
|
29
|
+
python3 "$SCRIPT" show-roadmap --root "$ROOT" >/dev/null
|
|
30
|
+
HTML="$CTX/roadmap/roadmap.html"
|
|
31
|
+
|
|
32
|
+
grep -q '<a class="lane-link" href="#node-1">' "$HTML"
|
|
33
|
+
grep -q '<section class="inline-details" hidden data-inline-details' "$HTML"
|
|
34
|
+
grep -q 'function setupInlineDetails()' "$HTML"
|
|
35
|
+
grep -q 'class="detail-card" id="node-1"' "$HTML"
|
|
36
|
+
|
|
37
|
+
if grep -q '<section class="inline-details" aria-label="Roadmap details">' "$HTML"; then
|
|
38
|
+
echo "inline details are visible by default" >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SKILL_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
|
5
|
+
SCRIPT="$SKILL_ROOT/scripts/context_guard.py"
|
|
6
|
+
HOOK="$SKILL_ROOT/scripts/context_guard_hook.py"
|
|
7
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-root-selection-XXXXXX")"
|
|
8
|
+
ROOT="$(cd "$ROOT" && pwd -P)"
|
|
9
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
10
|
+
|
|
11
|
+
mkdir -p "$ROOT/project"
|
|
12
|
+
git -C "$ROOT/project" init --quiet >/dev/null
|
|
13
|
+
|
|
14
|
+
if (cd "$SKILL_ROOT" && python3 "$SCRIPT" show-roadmap >/tmp/context-guard-implicit-skill-root.out 2>&1); then
|
|
15
|
+
echo "show-roadmap unexpectedly accepted the skill directory as implicit project root" >&2
|
|
16
|
+
exit 1
|
|
17
|
+
fi
|
|
18
|
+
grep -q 'refusing to use the Context Guard skill directory' /tmp/context-guard-implicit-skill-root.out
|
|
19
|
+
|
|
20
|
+
rm -rf "$SKILL_ROOT/.codex"
|
|
21
|
+
printf '{"cwd":"%s/project","prompt":"show roadmap"}' "$ROOT" | (
|
|
22
|
+
cd "$SKILL_ROOT"
|
|
23
|
+
python3 "$HOOK" session-start
|
|
24
|
+
) >/tmp/context-guard-hook-root.out
|
|
25
|
+
|
|
26
|
+
test -f "$ROOT/project/.codex/context/index.md"
|
|
27
|
+
test -f "$ROOT/project/.codex/context/roadmap.md"
|
|
28
|
+
if test -e "$SKILL_ROOT/.codex/context/roadmap.md"; then
|
|
29
|
+
echo "hook wrote project context into the skill directory" >&2
|
|
30
|
+
exit 1
|
|
31
|
+
fi
|
|
32
|
+
grep -q "$ROOT/project/.codex/context" /tmp/context-guard-hook-root.out
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py}"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-node-detail-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
|
|
8
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
9
|
+
python3 "$SCRIPT" set-language --language zh --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
CTX="$ROOT/.codex/context"
|
|
12
|
+
cat > "$CTX/roadmap.md" <<'MD'
|
|
13
|
+
# Context Roadmap
|
|
14
|
+
|
|
15
|
+
## Nodes
|
|
16
|
+
|
|
17
|
+
### NODE-20260626-001: 加入 Task Case 设计确认和 goal 阶段门控
|
|
18
|
+
|
|
19
|
+
- Date: 2026-06-26
|
|
20
|
+
- Status: done
|
|
21
|
+
- Level: major
|
|
22
|
+
- Branch: Main
|
|
23
|
+
- Parent: none
|
|
24
|
+
- Task: `CTX-20260626-test-chain`
|
|
25
|
+
- Outcome: Context Guard 要求复杂 Task Case 先给用户确认测试设计;goal 模式下把 Task Case 作为阶段门控。
|
|
26
|
+
- Decision / reason: 用户指出测试 case 应该是任务导向,而不是为每个 bug 造很多零散脚本。
|
|
27
|
+
- Avoid going back: 不要让 agent 静默创建大批未经确认的测试 case。
|
|
28
|
+
- Next: 继续观察 goal 模式下是否按阶段记录测试 checkpoint。
|
|
29
|
+
- Linked bad cases: BC-20260626-999
|
|
30
|
+
- Test chain: 节点详情页应显示用户问题、相关问题案例、采取方法和当前进度。
|
|
31
|
+
MD
|
|
32
|
+
|
|
33
|
+
cat > "$CTX/bad-cases.md" <<'MD'
|
|
34
|
+
# Bad Case Register
|
|
35
|
+
|
|
36
|
+
## Active Cases
|
|
37
|
+
|
|
38
|
+
### BC-20260626-999: 测试链路变成碎片化脚本
|
|
39
|
+
|
|
40
|
+
- Status: resolved
|
|
41
|
+
- First observed: 2026-06-26
|
|
42
|
+
- Last checked: 2026-06-26
|
|
43
|
+
- Scope: test-chain design
|
|
44
|
+
- Roadmap nodes: NODE-20260626-001
|
|
45
|
+
- Tags: #test-chain #context-bloat
|
|
46
|
+
- Phenomenon: agent 为每个 bug 创建零散脚本,真实任务流反而看不清。
|
|
47
|
+
- Trigger / reproduction: 让 agent 为多个历史 bad case 设计测试。
|
|
48
|
+
- Root cause: 测试链路没有以真实任务为单位组织。
|
|
49
|
+
- Fix method: 引入 task case 草案确认和阶段 checkpoint。
|
|
50
|
+
- Guard / verification: 检查节点详情页的相关问题案例和测试链路说明聚合在节点页面内。
|
|
51
|
+
MD
|
|
52
|
+
|
|
53
|
+
python3 "$SCRIPT" show-roadmap --root "$ROOT" >/dev/null
|
|
54
|
+
DETAIL="$CTX/roadmap/roadmap-details.html"
|
|
55
|
+
|
|
56
|
+
grep -q '用户提出的问题' "$DETAIL"
|
|
57
|
+
grep -q '相关问题案例' "$DETAIL"
|
|
58
|
+
grep -q '采取方法' "$DETAIL"
|
|
59
|
+
grep -q '当前进度' "$DETAIL"
|
|
60
|
+
grep -q '测试链路变成碎片化脚本' "$DETAIL"
|
|
61
|
+
grep -q '引入 task case 草案确认和阶段 checkpoint' "$DETAIL"
|
|
62
|
+
|
|
63
|
+
if grep -q '<h2 data-i18n="badCases">Bad Cases</h2>' "$DETAIL"; then
|
|
64
|
+
echo "detail page still renders a global bad-case list instead of node-scoped sections" >&2
|
|
65
|
+
exit 1
|
|
66
|
+
fi
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py}"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-readable-detail-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
|
|
8
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
9
|
+
python3 "$SCRIPT" set-language --language zh --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
CTX="$ROOT/.codex/context"
|
|
12
|
+
cat > "$CTX/roadmap.md" <<'MD'
|
|
13
|
+
# Context Roadmap
|
|
14
|
+
|
|
15
|
+
### NODE-20260627-001: 重构节点详情阅读页
|
|
16
|
+
- Date: 2026-06-27
|
|
17
|
+
- Status: done
|
|
18
|
+
- Level: major
|
|
19
|
+
- Branch: Main
|
|
20
|
+
- Outcome: Context Guard 现在承认用户截图、日志、复现和已定位根因可作为 red signal;证据足够时应停止补测试并进入实现。
|
|
21
|
+
- Decision / reason: 用户反馈旧详情页像列表堆料,不利于浏览;详情页应该围绕当前节点,而不是全局展开 bad case 列表;按 `;`、`;` 拆成长字段短条目时不能切碎代码片段;采取方法需要短行展示,不能把多个决策塞进一个段落。用户反馈 skill 又陷入测试循环,说明验证预算还不够,需要明确 stop condition。
|
|
22
|
+
- Avoid going back: 不要在节点详情里渲染全局 Bad Cases 长列表;不要把测试命令日志混入当前进度区;不要把采取方法渲染成一整段文字墙。
|
|
23
|
+
- Next: 保持节点详情只呈现当前节点的关键内容。
|
|
24
|
+
- Linked bad cases: BC-20260627-084
|
|
25
|
+
MD
|
|
26
|
+
|
|
27
|
+
cat > "$CTX/bad-cases.md" <<'MD'
|
|
28
|
+
# Bad Case Register
|
|
29
|
+
|
|
30
|
+
### BC-20260627-084: 节点详情采取方法像文字墙
|
|
31
|
+
- Status: resolved
|
|
32
|
+
- Roadmap nodes: NODE-20260627-001
|
|
33
|
+
- Tags: #roadmap-ux #readability
|
|
34
|
+
- Phenomenon: 节点详情的采取方法把多个长句拼成一段,用户很难扫读。
|
|
35
|
+
- Fix method: 将采取方法拆成短列表;相关问题案例留在当前节点内;进度区不混入测试命令日志。
|
|
36
|
+
- Guard / verification: 检查详情 HTML 中采取方法和当前进度使用 compact list。
|
|
37
|
+
MD
|
|
38
|
+
|
|
39
|
+
python3 "$SCRIPT" show-roadmap --root "$ROOT" >/dev/null
|
|
40
|
+
HTML="$CTX/roadmap/roadmap.html"
|
|
41
|
+
DETAIL="$CTX/roadmap/roadmap-details.html"
|
|
42
|
+
|
|
43
|
+
python3 - "$SCRIPT" <<'PY'
|
|
44
|
+
import importlib.util
|
|
45
|
+
import sys
|
|
46
|
+
|
|
47
|
+
script = sys.argv[1]
|
|
48
|
+
spec = importlib.util.spec_from_file_location("context_guard_under_test", script)
|
|
49
|
+
module = importlib.util.module_from_spec(spec)
|
|
50
|
+
assert spec.loader
|
|
51
|
+
spec.loader.exec_module(module)
|
|
52
|
+
items = module.split_detail_items("第一条;按 `;`、`;` 拆成长字段短条目时不能切碎代码片段;第三条。")
|
|
53
|
+
assert items == [
|
|
54
|
+
"第一条",
|
|
55
|
+
"按 `;`、`;` 拆成长字段短条目时不能切碎代码片段",
|
|
56
|
+
"第三条",
|
|
57
|
+
], items
|
|
58
|
+
assert module.polish_detail_zh(
|
|
59
|
+
"后续观察 stop hook 是否能让 Codex 在根因明确后先修复,再做一个最小 post-fix 检查。"
|
|
60
|
+
) == "下一步观察结束钩子能否提醒 Codex:根因明确后先修复,再做一次最小检查。"
|
|
61
|
+
PY
|
|
62
|
+
|
|
63
|
+
grep -q 'class="detail-list"' "$HTML"
|
|
64
|
+
grep -q 'class="detail-list"' "$DETAIL"
|
|
65
|
+
grep -q '<li>.*不要在节点详情里渲染全局 Bad Cases 长列表' "$DETAIL"
|
|
66
|
+
grep -q '<li>.*将采取方法拆成短列表' "$DETAIL"
|
|
67
|
+
grep -q '用户发现 Context Guard 又把时间耗在反复补测试上,因此需要给验证流程设置明确的停止条件' "$DETAIL"
|
|
68
|
+
grep -q '现在只要有截图、日志、复现步骤或明确根因,就可以确认问题已经成立' "$DETAIL"
|
|
69
|
+
grep -q '证据足够时,先修复问题,再做最小验证' "$DETAIL"
|
|
70
|
+
|
|
71
|
+
if grep -q '不要在节点详情里渲染全局 Bad Cases 长列表;不要把测试命令日志混入当前进度区;不要把采取方法渲染成一整段文字墙' "$DETAIL"; then
|
|
72
|
+
echo "method detail is still rendered as one paragraph wall" >&2
|
|
73
|
+
exit 1
|
|
74
|
+
fi
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py}"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-user-request-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
|
|
8
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
9
|
+
python3 "$SCRIPT" set-language --language zh --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
CTX="$ROOT/.codex/context"
|
|
12
|
+
python3 "$SCRIPT" checkpoint-roadmap-node \
|
|
13
|
+
--root "$ROOT" \
|
|
14
|
+
--title "改善节点详情可读性" \
|
|
15
|
+
--branch "Main" \
|
|
16
|
+
--level major \
|
|
17
|
+
--user-request "用户希望节点详情里的问题摘要直接来自用户输入,不要由 Codex 自由发挥。" \
|
|
18
|
+
--outcome "节点详情页现在优先展示 User request 字段。" \
|
|
19
|
+
--decision "这是内部实现决策,不应该冒充用户提出的问题。" \
|
|
20
|
+
--next-step "继续保持用户问题摘要和实现复盘分离。" >/dev/null
|
|
21
|
+
|
|
22
|
+
python3 "$SCRIPT" show-roadmap --root "$ROOT" >/dev/null
|
|
23
|
+
DETAIL="$CTX/roadmap/roadmap-details.html"
|
|
24
|
+
|
|
25
|
+
grep -q -- "- User request: 用户希望节点详情里的问题摘要直接来自用户输入" "$CTX/roadmap.md"
|
|
26
|
+
grep -q "用户希望节点详情里的问题摘要直接来自用户输入,不要由 Codex 自由发挥" "$DETAIL"
|
|
27
|
+
|
|
28
|
+
python3 - "$DETAIL" <<'PY'
|
|
29
|
+
from pathlib import Path
|
|
30
|
+
import re
|
|
31
|
+
import sys
|
|
32
|
+
|
|
33
|
+
html = Path(sys.argv[1]).read_text(encoding="utf-8")
|
|
34
|
+
match = re.search(r'<h4>.*?用户提出的问题.*?</h4>\s*<div>(?P<body>.*?)</div>', html, re.S)
|
|
35
|
+
assert match, "user-question section should render"
|
|
36
|
+
body = match.group("body")
|
|
37
|
+
assert "用户希望节点详情里的问题摘要直接来自用户输入" in body
|
|
38
|
+
assert "内部实现决策" not in body
|
|
39
|
+
assert "Outcome" not in body
|
|
40
|
+
PY
|
|
41
|
+
|
|
42
|
+
python3 "$SCRIPT" checkpoint-roadmap-node \
|
|
43
|
+
--root "$ROOT" \
|
|
44
|
+
--title "历史节点没有用户请求字段" \
|
|
45
|
+
--branch "Main" \
|
|
46
|
+
--level major \
|
|
47
|
+
--outcome "历史节点没有 User request 字段。" >/dev/null
|
|
48
|
+
|
|
49
|
+
python3 "$SCRIPT" show-roadmap --root "$ROOT" >/dev/null
|
|
50
|
+
grep -q "这个历史节点没有记录用户原始请求" "$DETAIL"
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py}"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-single-route-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
|
|
8
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
9
|
+
python3 "$SCRIPT" set-language --language zh --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
CTX="$ROOT/.codex/context"
|
|
12
|
+
cat > "$CTX/roadmap.md" <<'MD'
|
|
13
|
+
# Context Roadmap
|
|
14
|
+
|
|
15
|
+
## Nodes
|
|
16
|
+
|
|
17
|
+
### NODE-20260630-001: 收敛到模型记忆定位问题
|
|
18
|
+
|
|
19
|
+
- Date: 2026-06-30
|
|
20
|
+
- Status: done
|
|
21
|
+
- Level: major
|
|
22
|
+
- Branch: Main
|
|
23
|
+
- User request: 用户明确核心研究问题是模型的哪些层或部分能够记住目标数据,而不是训练流程本身。
|
|
24
|
+
- Outcome: 用户明确核心研究问题是模型的哪些层或部分能够记住目标数据,需要让路线图摘要完整可读。
|
|
25
|
+
- Next: 继续推进单主线。
|
|
26
|
+
- Linked bad cases: none
|
|
27
|
+
|
|
28
|
+
### NODE-20260630-002: 完成本地按需启动聊天原型
|
|
29
|
+
|
|
30
|
+
- Date: 2026-06-30
|
|
31
|
+
- Status: done
|
|
32
|
+
- Level: major
|
|
33
|
+
- Branch: Main
|
|
34
|
+
- User request: 用户希望完成本地 Web 聊天原型,并把相关问题案例和测试链路挂到节点下。
|
|
35
|
+
- Outcome: 创建了本地 Web 聊天原型,前端页面可调用 Qwen3-1.7B-Base。
|
|
36
|
+
- Next: 观察 worker 长时间运行问题。
|
|
37
|
+
- Linked bad cases: BC-20260630-001, BC-20260630-002
|
|
38
|
+
MD
|
|
39
|
+
|
|
40
|
+
cat > "$CTX/bad-cases.md" <<'MD'
|
|
41
|
+
# Bad Case Register
|
|
42
|
+
|
|
43
|
+
### BC-20260630-001: Base 模型回复重复对话模板
|
|
44
|
+
- Status: resolved
|
|
45
|
+
- Roadmap nodes: NODE-20260630-002
|
|
46
|
+
- Tags: #chat #model
|
|
47
|
+
- Phenomenon: Base 模型可能重复输出对话模板。
|
|
48
|
+
- Guard / verification: 运行短聊天请求,确认不会重复 continued chat transcript。
|
|
49
|
+
|
|
50
|
+
### BC-20260630-002: 默认生成长度导致 worker 长时间运行
|
|
51
|
+
- Status: resolved
|
|
52
|
+
- Roadmap nodes: NODE-20260630-002
|
|
53
|
+
- Tags: #runtime
|
|
54
|
+
- Phenomenon: 默认生成长度过长导致 worker 持续运行。
|
|
55
|
+
- Guard / verification: 运行短请求,确认响应能在合理时间返回。
|
|
56
|
+
MD
|
|
57
|
+
|
|
58
|
+
python3 "$SCRIPT" show-roadmap --root "$ROOT" >/dev/null
|
|
59
|
+
HTML="$CTX/roadmap/roadmap.html"
|
|
60
|
+
|
|
61
|
+
grep -q 'class="route-stack"' "$HTML"
|
|
62
|
+
if grep -q 'class="route-stack branch-map"' "$HTML"; then
|
|
63
|
+
echo "single-route roadmap should not use branch-map layout" >&2
|
|
64
|
+
exit 1
|
|
65
|
+
fi
|
|
66
|
+
grep -q '.route-stack:not(.branch-map) .track-grid' "$HTML"
|
|
67
|
+
grep -q 'min-height: auto;' "$HTML"
|
|
68
|
+
grep -q 'single-mainline' "$HTML"
|
|
69
|
+
grep -q '.track-column.route-column.no-test-line' "$HTML"
|
|
70
|
+
grep -q -- '-webkit-line-clamp: 3;' "$HTML"
|
|
71
|
+
|
|
72
|
+
if grep -q 'min-height: 430px;' "$HTML"; then
|
|
73
|
+
echo "single-route roadmap still reserves a large empty canvas" >&2
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
BODY="$(python3 - "$HTML" <<'PY'
|
|
78
|
+
from pathlib import Path
|
|
79
|
+
import sys
|
|
80
|
+
html = Path(sys.argv[1]).read_text()
|
|
81
|
+
print(html.split("</style>", 1)[1])
|
|
82
|
+
PY
|
|
83
|
+
)"
|
|
84
|
+
|
|
85
|
+
if grep -q 'track-label-column' <<<"$BODY"; then
|
|
86
|
+
echo "single-route roadmap should not show a left lane label column" >&2
|
|
87
|
+
exit 1
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
if grep -q 'data-lane="bad-cases"' <<<"$BODY"; then
|
|
91
|
+
echo "single-route roadmap should not render bad-case lanes in the overview" >&2
|
|
92
|
+
exit 1
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
if grep -q 'data-lane="test-chain"' <<<"$BODY"; then
|
|
96
|
+
echo "single-route roadmap should not render test-chain lanes in the overview" >&2
|
|
97
|
+
exit 1
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
if grep -q 'route-test-line' <<<"$BODY"; then
|
|
101
|
+
echo "single-route roadmap should not render the compact test route" >&2
|
|
102
|
+
exit 1
|
|
103
|
+
fi
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py}"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-display-title-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
|
|
8
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
9
|
+
python3 "$SCRIPT" set-language --language zh --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
CTX="$ROOT/.codex/context"
|
|
12
|
+
python3 "$SCRIPT" checkpoint-roadmap-node \
|
|
13
|
+
--root "$ROOT" \
|
|
14
|
+
--title "用用户请求字段驱动节点详情" \
|
|
15
|
+
--display-title "按用户原话解释节点" \
|
|
16
|
+
--branch "Main" \
|
|
17
|
+
--level major \
|
|
18
|
+
--user-request "用户希望节点标题和详情问题摘要更接近自己的原话。" \
|
|
19
|
+
--outcome "路线图节点现在可以用独立的人类展示标题。" \
|
|
20
|
+
--decision "source title 可以服务检索,但 overview 标题必须先服务阅读。" \
|
|
21
|
+
--next-step "后续创建节点时同时填写 Display title 和 User request。" >/dev/null
|
|
22
|
+
|
|
23
|
+
python3 "$SCRIPT" show-roadmap --root "$ROOT" >/dev/null
|
|
24
|
+
|
|
25
|
+
grep -q -- "- Display title: 按用户原话解释节点" "$CTX/roadmap.md"
|
|
26
|
+
grep -q "按用户原话解释节点" "$CTX/roadmap/roadmap.html"
|
|
27
|
+
grep -q "按用户原话解释节点" "$CTX/roadmap/roadmap-details.html"
|
|
28
|
+
|
|
29
|
+
if grep -q "用用户请求字段驱动节点详情" "$CTX/roadmap/roadmap.html"; then
|
|
30
|
+
echo "human roadmap should not expose the implementation-oriented source title" >&2
|
|
31
|
+
exit 1
|
|
32
|
+
fi
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py}"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-detail-summary-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
|
|
8
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
9
|
+
python3 "$SCRIPT" set-language --language zh --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
CTX="$ROOT/.codex/context"
|
|
12
|
+
python3 "$SCRIPT" checkpoint-roadmap-node \
|
|
13
|
+
--root "$ROOT" \
|
|
14
|
+
--title "新增详情摘要字段并调整渲染优先级" \
|
|
15
|
+
--display-title "节点详情读起来更顺" \
|
|
16
|
+
--branch "Main" \
|
|
17
|
+
--level major \
|
|
18
|
+
--user-request "用户希望节点详情里的进度、问题案例和方法都读起来通顺。" \
|
|
19
|
+
--progress-summary "已经让节点详情优先显示人类进度摘要,避免把 schema、CLI 和 HTML 投影说明直接展示给用户。" \
|
|
20
|
+
--method-summary "把 agent 源字段和用户阅读字段分开;有摘要时优先显示摘要,没有摘要时才回退到旧字段。" \
|
|
21
|
+
--outcome "roadmap node schema、CLI 和 HTML projection now support human-readable detail summaries." \
|
|
22
|
+
--decision "The renderer used raw source fields, which sounded like implementation logs." \
|
|
23
|
+
--linked-bad-cases "BC-20260630-089" >/dev/null
|
|
24
|
+
|
|
25
|
+
cat >> "$CTX/bad-cases.md" <<'EOF'
|
|
26
|
+
|
|
27
|
+
### BC-20260630-089: 节点详情字段拼接导致阅读不顺
|
|
28
|
+
|
|
29
|
+
- Status: resolved
|
|
30
|
+
- First observed: 2026-06-30
|
|
31
|
+
- Last checked: 2026-06-30
|
|
32
|
+
- Scope: roadmap details
|
|
33
|
+
- Roadmap nodes: NODE-20260630-001
|
|
34
|
+
- Tags: #roadmap-ux #readability
|
|
35
|
+
- Display summary: 详情页把实现记录直接展示出来,用户读起来像在看流水账。
|
|
36
|
+
- Phenomenon: User-facing detail sections reused roadmap outcome, decision, avoid, and bad-case phenomenon fields directly, creating stiff implementation prose.
|
|
37
|
+
- Fix method: Prefer human-written progress, method, and case display summaries before falling back to source fields.
|
|
38
|
+
- Guard / verification: Run this script and inspect node detail output.
|
|
39
|
+
EOF
|
|
40
|
+
|
|
41
|
+
python3 "$SCRIPT" show-roadmap --root "$ROOT" >/dev/null
|
|
42
|
+
DETAIL="$CTX/roadmap/roadmap-details.html"
|
|
43
|
+
|
|
44
|
+
grep -q -- "- Progress summary: 已经让节点详情优先显示人类进度摘要" "$CTX/roadmap.md"
|
|
45
|
+
grep -q -- "- Method summary: 把 agent 源字段和用户阅读字段分开" "$CTX/roadmap.md"
|
|
46
|
+
grep -q -- "- Display summary: 详情页把实现记录直接展示出来" "$CTX/bad-cases.md"
|
|
47
|
+
|
|
48
|
+
python3 - "$DETAIL" <<'PY'
|
|
49
|
+
from pathlib import Path
|
|
50
|
+
import re
|
|
51
|
+
import sys
|
|
52
|
+
|
|
53
|
+
html = Path(sys.argv[1]).read_text(encoding="utf-8")
|
|
54
|
+
card = re.search(r'<section class="detail-card" id="node-1">(?P<body>.*?)</section>\s*</div>\s*</section>', html, re.S)
|
|
55
|
+
assert card, "node detail card should exist"
|
|
56
|
+
body = card.group("body")
|
|
57
|
+
assert "已经让节点详情优先显示人类进度摘要" in body
|
|
58
|
+
assert "把 agent 源字段和用户阅读字段分开" in body
|
|
59
|
+
assert "详情页把实现记录直接展示出来,用户读起来像在看流水账" in body
|
|
60
|
+
assert "roadmap node schema、CLI 和 HTML projection" not in body
|
|
61
|
+
assert "The renderer used raw source fields" not in body
|
|
62
|
+
assert "User-facing detail sections reused" not in body
|
|
63
|
+
PY
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
SCRIPT="${1:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/scripts/context_guard.py}"
|
|
5
|
+
ROOT="$(mktemp -d "${TMPDIR:-/tmp}/context-guard-approved-tests-XXXXXX")"
|
|
6
|
+
trap 'rm -rf "$ROOT"' EXIT
|
|
7
|
+
|
|
8
|
+
python3 "$SCRIPT" init --root "$ROOT" >/dev/null
|
|
9
|
+
python3 "$SCRIPT" set-language --language zh --root "$ROOT" >/dev/null
|
|
10
|
+
|
|
11
|
+
CTX="$ROOT/.codex/context"
|
|
12
|
+
cat > "$CTX/roadmap.md" <<'MD'
|
|
13
|
+
# Context Roadmap
|
|
14
|
+
|
|
15
|
+
## Nodes
|
|
16
|
+
|
|
17
|
+
### NODE-20260701-001: 主线阶段
|
|
18
|
+
|
|
19
|
+
- Date: 2026-07-01
|
|
20
|
+
- Status: done
|
|
21
|
+
- Level: major
|
|
22
|
+
- Branch: Main
|
|
23
|
+
- Display title: 主线阶段
|
|
24
|
+
- Outcome: 主线阶段完成。
|
|
25
|
+
- Linked bad cases: BC-20260701-001
|
|
26
|
+
|
|
27
|
+
### NODE-20260701-002: 支线阶段
|
|
28
|
+
|
|
29
|
+
- Date: 2026-07-01
|
|
30
|
+
- Status: done
|
|
31
|
+
- Level: major
|
|
32
|
+
- Branch: 支线
|
|
33
|
+
- Parent: NODE-20260701-001
|
|
34
|
+
- Display title: 支线阶段
|
|
35
|
+
- Outcome: 支线阶段完成。
|
|
36
|
+
- Linked bad cases: BC-20260701-002
|
|
37
|
+
MD
|
|
38
|
+
|
|
39
|
+
cat > "$CTX/bad-cases.md" <<'MD'
|
|
40
|
+
# Bad Case Register
|
|
41
|
+
|
|
42
|
+
### BC-20260701-001: 普通 bad case guard 不应显示为测试
|
|
43
|
+
- Status: resolved
|
|
44
|
+
- Roadmap nodes: NODE-20260701-001
|
|
45
|
+
- Tags: #roadmap-ux
|
|
46
|
+
- Phenomenon: 普通 bad case guard 被误当成用户测试。
|
|
47
|
+
- Guard / verification: 这是普通复发检查,不是用户批准测试。
|
|
48
|
+
|
|
49
|
+
### BC-20260701-002: 用户批准测试应显示
|
|
50
|
+
- Status: resolved
|
|
51
|
+
- Roadmap nodes: NODE-20260701-002
|
|
52
|
+
- Tags: #roadmap-ux
|
|
53
|
+
- Phenomenon: 用户批准的测试需要显示在线路上。
|
|
54
|
+
- Guard / verification: 运行用户确认的测试。
|
|
55
|
+
- Run policy: every-dev-completion
|
|
56
|
+
MD
|
|
57
|
+
|
|
58
|
+
python3 "$SCRIPT" show-roadmap --root "$ROOT" >/dev/null
|
|
59
|
+
HTML="$CTX/roadmap/roadmap.html"
|
|
60
|
+
BODY="$(python3 - "$HTML" <<'PY'
|
|
61
|
+
from pathlib import Path
|
|
62
|
+
import sys
|
|
63
|
+
html = Path(sys.argv[1]).read_text()
|
|
64
|
+
print(html.split("</style>", 1)[1])
|
|
65
|
+
PY
|
|
66
|
+
)"
|
|
67
|
+
|
|
68
|
+
python3 - <<'PY' "$HTML"
|
|
69
|
+
from pathlib import Path
|
|
70
|
+
import sys
|
|
71
|
+
import re
|
|
72
|
+
html = Path(sys.argv[1]).read_text()
|
|
73
|
+
body = html.split("</style>", 1)[1]
|
|
74
|
+
notes = re.findall(r'<a class="route-test-note"[^>]*>(.*?)</a>', body, re.S)
|
|
75
|
+
joined = "\n".join(notes)
|
|
76
|
+
if "用户批准测试应显示" not in joined:
|
|
77
|
+
raise SystemExit("approved test did not appear in the route test line")
|
|
78
|
+
if "普通 bad case guard 不应显示为测试" in joined:
|
|
79
|
+
raise SystemExit("ordinary linked bad-case guard appeared as a test route item")
|
|
80
|
+
test_items = len(notes)
|
|
81
|
+
if test_items != 1:
|
|
82
|
+
raise SystemExit(f"expected exactly one approved test route item, got {test_items}")
|
|
83
|
+
PY
|