🐛 fix(tsl-syntax-reference): check fence language per block identity

- `--check` now requires `反例 / 不可照写` in a text fence and
  `可直接照写示例` in a tsl fence; the AGENTS.md flow that extracts every
  ```tsl block and runs it would otherwise execute a counterexample as if
  it were a valid example, and an example hidden in a text fence would
  never be extracted for verification
- 10 held the only counterexample in a tsl fence (a local function call
  with a trailing `with array(...)`); the rule and that fix cannot land in
  separate commits or --check fails in between
- 配置片段 / 概念骨架 and 仅服务端可执行示例 stay unconstrained, since both
  languages are in use for them today

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
csh
2026-07-30 21:33:14 +08:00
co-authored by Claude Opus 5
parent bcad28d22c
commit 68a3b852b0
2 changed files with 24 additions and 3 deletions
@@ -420,7 +420,7 @@ end;
代码块身份:反例 / 不可照写
```tsl
```text
cached_result := Demo() with array("a": 11);
function Demo();
+23 -2
View File
@@ -35,6 +35,13 @@ ALLOWED_IDENTITIES = {
"配置片段 / 概念骨架",
"仅服务端可执行示例",
}
# 身份与围栏语言的固定对应。反例必须留在 text 围栏:批量抽取 ```tsl 块实跑的
# 流程会把 tsl 围栏里的反例当正例执行;反过来照写示例落进 text 围栏就永远不会
# 被抽出来验证。其余身份(概念骨架、仅服务端示例)按页面需要自行选择语言。
IDENTITY_FENCE_LANGUAGES = {
"反例 / 不可照写": "text",
"可直接照写示例": "tsl",
}
ROUTER_PHRASES = ("路由中心", "选择一个主专题", "候选页继续判断")
EXCLUDED_REFERENCE_FILES = {"index.md"}
DUTY_HEADING = "本篇职责"
@@ -411,16 +418,30 @@ def _identity_problems(page: Path, lines: list[str]) -> list[ValidationProblem]:
problems.append(ValidationProblem(page, index, f"未知身份:{identity}"))
in_fence = False
for index, line in enumerate(lines):
if FENCE_RE.match(line):
fence = FENCE_RE.match(line)
if fence:
if in_fence:
in_fence = False
else:
if _associated_identity(lines, index) is None:
identity = _associated_identity(lines, index)
if identity is None:
problems.append(
ValidationProblem(
page, index + 1, "每个代码围栏必须关联恰好一个代码块身份"
)
)
else:
expected = IDENTITY_FENCE_LANGUAGES.get(identity)
language = (fence.group(1) or "").strip()
if expected is not None and language != expected:
problems.append(
ValidationProblem(
page,
index + 1,
f"{identity}」必须写在 ```{expected} 围栏里,"
f"当前是 ```{language or '(无语言标注)'}",
)
)
in_fence = True
continue
if not in_fence and SUSPICIOUS_FENCE_RE.match(line):