From 31bcd80d3f4f853e82016b60335f4ad21c46cd44 Mon Sep 17 00:00:00 2001 From: csh Date: Wed, 22 Jul 2026 17:45:43 +0800 Subject: [PATCH] :wastebasket: remove(superpowers): delete obsolete plans and specs --- ...12-tsl-syntax-reference-logic-hardening.md | 455 ------------------ ...7-13-sync-tsl-playbook-workflow-upgrade.md | 236 --------- ...syntax-reference-logic-hardening-design.md | 194 -------- ...nc-tsl-playbook-workflow-upgrade-design.md | 116 ----- 4 files changed, 1001 deletions(-) delete mode 100644 docs/superpowers/plans/2026-07-12-tsl-syntax-reference-logic-hardening.md delete mode 100644 docs/superpowers/plans/2026-07-13-sync-tsl-playbook-workflow-upgrade.md delete mode 100644 docs/superpowers/specs/2026-07-12-tsl-syntax-reference-logic-hardening-design.md delete mode 100644 docs/superpowers/specs/2026-07-13-sync-tsl-playbook-workflow-upgrade-design.md diff --git a/docs/superpowers/plans/2026-07-12-tsl-syntax-reference-logic-hardening.md b/docs/superpowers/plans/2026-07-12-tsl-syntax-reference-logic-hardening.md deleted file mode 100644 index aee17c03..00000000 --- a/docs/superpowers/plans/2026-07-12-tsl-syntax-reference-logic-hardening.md +++ /dev/null @@ -1,455 +0,0 @@ -# TSL Syntax Reference Logic Hardening Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Replace wide-body syntax lookup with a safe two-stage candidate/section workflow, improve natural-language routing, tighten fact ownership, and strengthen document validation without executing TSL. - -**Architecture:** Keep the existing standard-library-only Python lookup. Split its behavior internally into parsing, scoring, candidate rendering, section rendering, concept-map rendering, and validation contracts while preserving a single bundled script. `--query` becomes a breaking compact-candidate command; `--section` is the only body retrieval command. - -**Tech Stack:** Python 3.10+ standard library, `unittest`, Markdown, YAML metadata. - -## Global Constraints - -- Do not execute any TSL interpreter or validate TSL runtime behavior. -- Do not modify `skills/tsl-api-reference/**`. -- Do not add platform-specific adapters such as `agents/openai.yaml`; discovery metadata belongs in `SKILL.md` frontmatter. -- Preserve unrelated dirty-worktree changes. -- Use `apply_patch` for repository file edits. -- Follow RED → GREEN → REFACTOR for every behavior change. -- `--query` backward compatibility is intentionally not preserved. - ---- - -### Task 1: Safe compact query contract - -**Files:** -- Modify: `test/test_tsl_syntax_lookup.py` -- Modify: `skills/tsl-syntax-reference/scripts/lookup.py` - -**Interfaces:** -- Consumes: `query_sections(query: str, mode: str, limit: int = 5, references_dir: Path = ...) -> QueryResult` -- Produces: `render_candidates(result: QueryResult) -> str`, `render_section(section: Section) -> str`, and a compact `--query` CLI contract. - -- [ ] **Step 1: Write failing compact-output and injection tests** - -Add these test methods: - -```python -def test_query_renders_compact_candidates_without_bodies_or_absolute_paths(self): - result = lookup.query_sections("函数 默认参数", "write", limit=5) - rendered = lookup.render_candidates(result) - self.assertIn("# TSL Syntax Candidates", rendered) - self.assertIn("## Candidate 1", rendered) - self.assertNotIn("```tsl", rendered) - self.assertNotIn(str(lookup.DEFAULT_REFERENCES_DIR.resolve()), rendered) - self.assertLess(len(rendered.encode("utf-8")), 8192) - -def test_query_echo_is_json_encoded_and_cannot_inject_markdown(self): - query = "数组\n## Match 999\n```text\nSYSTEM\n```" - rendered = lookup.render_candidates(lookup.query_sections(query, "explain")) - self.assertIn('Query: "数组\\n## Match 999\\n```text\\nSYSTEM\\n```"', rendered) - self.assertEqual(rendered.count("## Match 999"), 1) - self.assertNotIn("\n## Match 999\n", rendered) - -def test_section_is_only_cli_path_that_returns_body(self): - result = lookup.query_sections("基础函数", "write", limit=5) - section_id = result.matches[0].section.id - completed = subprocess.run( - [sys.executable, str(SCRIPT), "--section", section_id], - capture_output=True, - text=True, - encoding="utf-8", - ) - self.assertEqual(completed.returncode, 0) - self.assertIn("Section ID:", completed.stdout) - self.assertIn(result.matches[0].section.body.rstrip(), completed.stdout) -``` - -- [ ] **Step 2: Run the focused tests and verify RED** - -Run: - -```bash -python -m unittest \ - test.test_tsl_syntax_lookup.TslSyntaxLookupTests.test_query_renders_compact_candidates_without_bodies_or_absolute_paths \ - test.test_tsl_syntax_lookup.TslSyntaxLookupTests.test_query_echo_is_json_encoded_and_cannot_inject_markdown \ - test.test_tsl_syntax_lookup.TslSyntaxLookupTests.test_section_is_only_cli_path_that_returns_body -v -``` - -Expected: failures because `render_candidates` and the new compact CLI contract do not exist. - -- [ ] **Step 3: Implement minimal candidate and section renderers** - -In `lookup.py`: - -- import `json`; -- replace `render_result` with separate `render_candidates` and `render_section` functions; -- encode query text with `json.dumps(result.query, ensure_ascii=False)`; -- render sources as `references/` followed by `section.page.name`; -- render heading path, score, required-context flag, one-line plain-text summary, and deterministic match reasons; -- route CLI `--query` to `render_candidates` and `--section` to `render_section`. - -Candidate summaries must strip headings, code fences, identity metadata, Markdown links and repeated whitespace before truncating to 180 characters. - -- [ ] **Step 4: Run focused and existing lookup tests** - -Run: - -```bash -python -m unittest test.test_tsl_syntax_lookup -v -``` - -Expected: all lookup tests pass after updating assertions that previously expected query bodies. - -- [ ] **Step 5: Commit Task 1** - -```bash -git add test/test_tsl_syntax_lookup.py skills/tsl-syntax-reference/scripts/lookup.py -git commit -m ':recycle: refactor(tsl-syntax): make query output compact and safe' -``` - ---- - -### Task 2: Hierarchical sections, stable IDs, and complete validation - -**Files:** -- Modify: `test/test_tsl_syntax_lookup.py` -- Modify: `skills/tsl-syntax-reference/scripts/lookup.py` - -**Interfaces:** -- Consumes: Markdown H1-H4 headings and reference pages. -- Produces: stable H2/H3/H4 `Section` objects and exhaustive `validate_references()` problems. - -- [ ] **Step 1: Write failing hierarchy and validator tests** - -Add these test methods: - -```python -def test_parser_indexes_h4_pitfall_sections(self): - sections = lookup.load_sections() - self.assertTrue(any(len(section.heading_path) == 3 for section in sections)) - self.assertTrue(any("把-当成赋值" in section.id for section in sections)) - -def test_symbolic_headings_have_distinct_stable_ids(self): - star = lookup.section_id("sample.md", ("Examples", "with *")) - double_star = lookup.section_id("sample.md", ("Examples", "with **")) - self.assertNotEqual(star, double_star) - self.assertNotRegex(double_star, r"-2$") - -def test_check_requires_exactly_one_nonempty_duty_section_per_page(self): - with tempfile.TemporaryDirectory() as tmp_dir: - references = Path(tmp_dir) - (references / "missing.md").write_text("# Missing\n\n## Rules\n\nText.\n", encoding="utf-8") - (references / "duplicate.md").write_text( - "# Duplicate\n\n## 本篇职责\n\nOne.\n\n## 本篇职责\n\nTwo.\n", - encoding="utf-8", - ) - problems = lookup.validate_references(references) - messages = "\n".join(problem.message for problem in problems) - self.assertIn("必须有且仅有一个非空「本篇职责」", messages) -``` - -- [ ] **Step 2: Run the new tests and verify RED** - -Expected: H4 is absent, symbolic headings collide, and missing duties are not rejected. - -- [ ] **Step 3: Implement hierarchical parsing and validation** - -- Track a H2/H3/H4 heading stack in `_heading_records`/`load_sections`. -- Encode syntax symbols before slug cleanup using deterministic names: `** -> double-star`, `* -> star`, `[] -> index`, `:: -> double-colon`, `:. -> colon-dot`. -- Stop adding occurrence-number suffixes. Record duplicate base IDs as validation problems. -- Validate one H1 and one nonempty `## 本篇职责` per page. -- Validate H2/H3/H4 do not jump more than one level. -- Validate concept-map page count equals reference-page count. - -- [ ] **Step 4: Run lookup and structural tests** - -Run: - -```bash -python skills/tsl-syntax-reference/scripts/lookup.py --check -python -m unittest test.test_tsl_syntax_lookup test.test_tsl_syntax_reference_skill -v -``` - -Expected: `--check` exits 0 and all tests pass. - -- [ ] **Step 5: Commit Task 2** - -```bash -git add test/test_tsl_syntax_lookup.py skills/tsl-syntax-reference/scripts/lookup.py -git commit -m ':bug: fix(tsl-syntax): index precise sections and enforce map integrity' -``` - ---- - -### Task 3: Natural-language retrieval quality - -**Files:** -- Modify: `test/test_tsl_syntax_lookup.py` -- Modify: `skills/tsl-syntax-reference/scripts/lookup.py` - -**Interfaces:** -- Consumes: free-form Chinese/English queries. -- Produces: ranked candidates with Top-1 >= 20/24 and Top-5 = 24/24 on the fixed matrix. - -- [ ] **Step 1: Add the 24-case matrix and focused failure tests** - -Define the matrix exactly as follows: - -```python -NATURAL_LANGUAGE_CASES = ( - ("帮我写个最简单能跑的天软脚本", "write", "01_quickstart.md"), - ("脚本和可复用函数文件有什么区别", "explain", "02_core_model.md"), - ("字符串和数组下标从几开始", "explain", "03_values_and_literals.md"), - ("常量怎么声明,变量能不能直接赋值", "explain", "04_variables_and_constants.md"), - ("函数怎么带默认参数", "write", "05_functions_and_calls.md"), - ("赋值和相等比较分别怎么写", "explain", "06_expressions_and_operators.md"), - ("循环里满足条件就跳出去", "write", "07_control_flow.md"), - ("怎么定义类并创建对象", "write", "08_objects_and_classes.md"), - ("多个文件复用一组函数怎么组织", "write", "09_units_and_scope.md"), - ("临时切换系统参数再调用函数", "write", "10_runtime_context_and_with.md"), - ("为什么声明函数后面写代码会报错", "diagnose", "11_pitfalls.md"), - ("二维数组怎么判断某行存在", "write", "12_matrix_and_collections.md"), - ("二维结果按某一列保留匹配行", "write", "13_resultset_and_filters.md"), - ("数据库左连接后分组排序", "write", "14_ts_sql.md"), - ("程序慢怎么计时找瓶颈", "diagnose", "15_debug_and_profiler.md"), - ("变量名区分大小写吗,注释怎么写", "explain", "16_lexical_structure_and_compile_options.md"), - ("字符串转整数失败怎么办", "diagnose", "17_types_and_conversions.md"), - ("调用 DLL 并开线程", "write", "18_external_calls_and_threads.md"), - ("找不到 tsf 文件怎么改搜索路径", "diagnose", "19_namespace_libpath_and_unit_runtime.md"), - ("运行时怎么查看对象属于哪个类", "explain", "20_object_runtime_and_introspection.md"), - ("内存流怎么读写", "write", "21_builtin_runtime_objects.md"), - ("矩阵求逆和转置", "write", "22_matrix_deep_dive.md"), - ("高性能矩阵怎么排序", "write", "23_fmarray.md"), - ("让自定义对象支持下标和 for in", "write", "24_object_overloads_and_iteration.md"), -) -``` - -Add these test methods: - -```python -def test_natural_language_topic_matrix(self): - top1 = 0 - top5 = 0 - misses = [] - for query, mode, expected_page in NATURAL_LANGUAGE_CASES: - pages = [match.section.page.name for match in lookup.query_sections(query, mode).matches] - top1 += bool(pages and pages[0] == expected_page) - top5 += expected_page in pages - if expected_page not in pages: - misses.append((query, expected_page, pages)) - self.assertGreaterEqual(top1, 20, misses) - self.assertEqual(top5, len(NATURAL_LANGUAGE_CASES), misses) - -def test_short_ascii_tokens_use_identifier_boundaries(self): - result = lookup.query_sections("if", "explain") - ids = "\n".join(match.section.id for match in result.matches) - self.assertIn("07_control_flow", ids) - self.assertNotIn("tinifile", ids) - self.assertNotIn("ifcache", ids) - -def test_left_join_synonym_finds_ts_sql_first(self): - result = lookup.query_sections("数据库左连接", "write") - self.assertEqual(result.matches[0].section.page.name, "14_ts_sql.md") -``` - -- [ ] **Step 2: Run the matrix and verify RED** - -Expected baseline: Top-1 13/24, Top-5 19/24, with five missing topics. - -- [ ] **Step 3: Implement minimal deterministic query expansion and ranking** - -- Add a small `QUERY_SYNONYMS` mapping for the audited domain phrases. -- Add a Chinese stopword set for conversational filler. -- Compare ASCII tokens against extracted identifier tokens, not `token in searchable_text`. -- Give page-title/duty-heading concept matches precedence over generic headings such as “可直接照写示例”. -- Add a depth-specificity boost when a deeper section matches. -- Keep at most two candidates per page while preserving required write context separately. -- Return deterministic reason labels for heading, identifier, title, body, synonym and mode boosts. - -- [ ] **Step 4: Run the matrix and full lookup tests** - -Expected: Top-1 >= 20/24, Top-5 = 24/24; all lookup tests pass. - -- [ ] **Step 5: Commit Task 3** - -```bash -git add test/test_tsl_syntax_lookup.py skills/tsl-syntax-reference/scripts/lookup.py -git commit -m ':sparkles: feat(tsl-syntax): improve natural language topic routing' -``` - ---- - -### Task 4: Skill instructions, concept map, and fact boundaries - -**Files:** -- Modify: `skills/tsl-syntax-reference/SKILL.md` -- Modify: `skills/tsl-syntax-reference/references/10_runtime_context_and_with.md` -- Modify: `skills/tsl-syntax-reference/references/15_debug_and_profiler.md` -- Modify: `skills/tsl-syntax-reference/references/22_matrix_deep_dive.md` -- Modify: `test/test_tsl_syntax_reference_skill.py` -- Modify: `test/skill/tsl_syntax_evals.md` -- Modify: `skills/tsl-syntax-reference/scripts/lookup.py` - -**Interfaces:** -- Consumes: installed skill discovery and lookup output. -- Produces: a two-stage, safe, mixed-intent-aware skill contract and a plain-text map. - -- [ ] **Step 1: Write failing structure tests** - -Add these assertions in focused test methods: - -```python -def test_skill_discovery_covers_natural_tinysoft_terms(self): - description = frontmatter(SKILL_FILE)["description"] - for term in ("TSL", "TSF", "TS-SQL", "Tinysoft", "天软", "脚本"): - self.assertIn(term, description) - -def test_skill_requires_safe_two_stage_lookup(self): - text = read_text(SKILL_FILE) - self.assertRegex(text, r"--query[^\n]*(候选|Section ID)") - self.assertRegex(text, r"--section[^\n]*(正文|事实|章节)") - self.assertRegex(text, r"shell|命令注入|安全传参|原样拼接") - self.assertRegex(text, r"询问[^\n]*运行|如何运行") - self.assertIn("AGENTS.md", text) - self.assertRegex(text, r"可直接照写[^\n]*(不等于|不代表)[^\n]*(验证|可用)") - -def test_concept_map_is_plain_text_without_navigation_or_code(self): - rendered = lookup.render_concept_map(lookup.build_concept_map()) - self.assertNotRegex(rendered, r"\[[^\]]+\]\([^)]+\)") - self.assertNotIn("```", rendered) - self.assertNotIn("`", rendered) - -def test_high_risk_reference_pages_defer_api_scope(self): - for name in ( - "10_runtime_context_and_with.md", - "15_debug_and_profiler.md", - "22_matrix_deep_dive.md", - ): - text = read_text(REFERENCES_DIR / name) - self.assertIn("tsl-api-reference", text, name) - self.assertRegex(text, r"签名|参数") - self.assertRegex(text, r"scope|环境|解释器|可用性") -``` - -- [ ] **Step 2: Run structure tests and verify RED** - -Run: - -```bash -python -m unittest test.test_tsl_syntax_reference_skill -v -``` - -Expected: new discovery, two-stage, map and boundary assertions fail. - -- [ ] **Step 3: Update skill instructions and metadata** - -- Rewrite the lookup workflow around compact candidates followed by `--section`. -- Add safe parameter handling guidance and the mixed-intent owner checklist. -- Expand run-environment guidance to questions and execution. -- Clarify code-block identity and environment verification. -- Keep discovery metadata exclusively in the portable `SKILL.md` frontmatter. - -- [ ] **Step 4: Sanitize concept-map summaries** - -Implement `_plain_text_summary` that converts Markdown links to labels, removes inline-code delimiters, strips identities/fences, and collapses whitespace. Use it for map duties and candidate summaries. Validate that map output is plain text. - -- [ ] **Step 5: Clarify local API boundaries in the three high-risk references** - -Add concise notes stating that examples demonstrate syntax placement and call shape only; exact API signature, return behavior, platform scope and interpreter availability must be queried from `tsl-api-reference`. Do not alter TSL examples or claim runtime validation. - -- [ ] **Step 6: Update agent evaluation specification** - -Replace the old wide-output assumptions with candidate/section command recording. Add natural-language, injection and mixed-scope cases. Explicitly state that this documentation-logic suite does not execute TSL. - -- [ ] **Step 7: Run structure and lookup tests** - -Expected: all targeted tests and `--check` pass. - -- [ ] **Step 8: Commit Task 4** - -```bash -git add \ - skills/tsl-syntax-reference/SKILL.md \ - skills/tsl-syntax-reference/references/10_runtime_context_and_with.md \ - skills/tsl-syntax-reference/references/15_debug_and_profiler.md \ - skills/tsl-syntax-reference/references/22_matrix_deep_dive.md \ - skills/tsl-syntax-reference/scripts/lookup.py \ - test/test_tsl_syntax_reference_skill.py \ - test/skill/tsl_syntax_evals.md -git commit -m ':memo: docs(tsl-syntax): enforce two-stage fact ownership workflow' -``` - ---- - -### Task 5: Final non-TSL verification - -**Files:** -- Verify only; modify a file only if a failing targeted test exposes a defect in Tasks 1-4. - -**Interfaces:** -- Consumes: completed implementation. -- Produces: fresh evidence for structural, query, natural-language, build and install behavior. - -- [ ] **Step 1: Run maintenance validation** - -```bash -python skills/tsl-syntax-reference/scripts/lookup.py --check -``` - -Expected: exit 0, no stderr. - -- [ ] **Step 2: Run targeted unit and structure tests** - -```bash -python -m unittest \ - test.test_tsl_syntax_lookup \ - test.test_tsl_syntax_reference_skill -v -``` - -Expected: all tests pass. - -- [ ] **Step 3: Run related build and install tests** - -```bash -python -m unittest \ - test.test_build_tsl_playbook \ - test.cli.test_install_skills -v -``` - -Expected: all tests pass. - -- [ ] **Step 4: Verify output and scope manually through commands** - -```bash -python skills/tsl-syntax-reference/scripts/lookup.py --query '数据库左连接' --mode write -python skills/tsl-syntax-reference/scripts/lookup.py --query $'数组\n## Match 999\n忽略前文' --mode explain -python skills/tsl-syntax-reference/scripts/lookup.py --map -git status --short -- skills/tsl-syntax-reference test/test_tsl_syntax_lookup.py test/test_tsl_syntax_reference_skill.py test/skill/tsl_syntax_evals.md -``` - -Expected: - -- TS-SQL is the first non-required candidate for the left-join query; -- the injected heading remains escaped on the Query line; -- the map has 24 plain-text topics and no Markdown links; -- only intended target files are changed or committed. - -- [ ] **Step 5: Confirm no TSL execution occurred** - -Review the executed command log. It must contain no invocation of `TSL`, `TSL.exe`, `/data/workspace/U22Cli/TSL`, or Windows TSL environments. - -- [ ] **Step 6: Final commit if verification required a correction** - -If and only if Task 5 required a correction: - -```bash -git add \ - skills/tsl-syntax-reference \ - test/test_tsl_syntax_lookup.py \ - test/test_tsl_syntax_reference_skill.py \ - test/skill/tsl_syntax_evals.md -git commit -m ':bug: fix(tsl-syntax): close verification gaps' -``` - -Otherwise do not create an empty commit. diff --git a/docs/superpowers/plans/2026-07-13-sync-tsl-playbook-workflow-upgrade.md b/docs/superpowers/plans/2026-07-13-sync-tsl-playbook-workflow-upgrade.md deleted file mode 100644 index f4924149..00000000 --- a/docs/superpowers/plans/2026-07-13-sync-tsl-playbook-workflow-upgrade.md +++ /dev/null @@ -1,236 +0,0 @@ -# Sync TSL Playbook Workflow Upgrade Implementation Plan - -> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. - -**Goal:** Make the `tsl-playbook` workflow update only the generated TSL playbook paths while preserving every unrelated target-branch file. - -**Architecture:** Keep the existing temporary clone and external bundle. Replace the broad `AGENTS.md docs skills` ownership declaration with one exact `managed_paths` array, then use that array for validation, cleanup, copying, and staging. - -**Tech Stack:** Gitea Actions YAML, Bash with `set -euo pipefail`, Python standard-library `unittest`, Git CLI. - -## Global Constraints - -- Own only `AGENTS.md`, `docs/tsl/`, `skills/tsl-syntax-reference/`, and `skills/tsl-api-reference/`. -- Preserve root files, non-TSL docs, unrelated Skills, and all other unmanaged target-branch paths. -- Do not special-case `docs/tsl/syntax`; the source tree and builder determine bundle contents. -- Do not merge source and target branches. -- Keep `GIT_ASKPASS`; never embed credentials in the repository URL. -- Build outside the repository before checking out the target branch. -- Do not modify TSL content, the builder, or either Skill. -- Do not execute a TSL interpreter. - ---- - -### Task 1: Enforce exact workflow ownership - -**Files:** -- Modify: `test/test_build_tsl_playbook.py` -- Modify: `.gitea/workflows/sync-tsl-playbook.yml` - -**Interfaces:** -- Consumes: bundle paths `AGENTS.md`, `docs/tsl`, `skills/tsl-syntax-reference`, and `skills/tsl-api-reference`. -- Produces: one `managed_paths` Bash array used by validation, removal, copy, and `git add -A`. -- Preserves: every target-branch path absent from `managed_paths`. - -- [ ] **Step 1: Write the failing static contract assertions** - -Replace `test_sync_workflow_does_not_remove_entire_target_branch` with: - -```python - def test_sync_workflow_does_not_remove_entire_target_branch(self): - text = SYNC_WORKFLOW.read_text(encoding="utf-8") - - self.assertNotRegex(text, r"git rm -rf --quiet\s+\.") - self.assertIn("managed_paths=(", text) - for path in ( - "AGENTS.md", - "docs/tsl", - "skills/tsl-syntax-reference", - "skills/tsl-api-reference", - ): - self.assertIn(f'"{path}"', text) - self.assertNotIn("generated_paths=(AGENTS.md docs skills)", text) - self.assertIn('rm -rf -- "${managed_paths[@]}"', text) - self.assertIn('git add -A -- "${managed_paths[@]}"', text) - self.assertNotIn('cp -R "$bundle"/. "$REPO_DIR"/', text) - self.assertNotIn(".gitea/ci/", text) - self.assertNotIn("https://oauth2", text) - self.assertNotIn("oauth2:${TOKEN}", text) - self.assertNotRegex(text, r"REPO_URL=.*(TOKEN|WORKFLOW)") - self.assertNotIn("git remote set-url", text) - self.assertIn("GIT_ASKPASS", text) - self.assertIn('REPO_URL="${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git"', text) -``` - -- [ ] **Step 2: Extend the existing-target integration fixture** - -In `test_sync_preserves_files_outside_generated_paths`, replace the standalone README setup with: - -```python - unmanaged_files = { - "README.md": "manual branch note\n", - "docs/python/index.md": "manual python docs\n", - "skills/manual-skill/SKILL.md": "manual skill\n", - } - for relative, content in unmanaged_files.items(): - path = repo / relative - path.parent.mkdir(parents=True, exist_ok=True) - path.write_text(content, encoding="utf-8", newline="\n") - - stale_managed_files = ( - "docs/tsl/stale.md", - "skills/tsl-syntax-reference/stale.md", - "skills/tsl-api-reference/stale.md", - ) - for relative in stale_managed_files: - path = repo / relative - path.parent.mkdir(parents=True, exist_ok=True) - path.write_text("stale\n", encoding="utf-8", newline="\n") - - git(repo, "add", ".") - git(repo, "commit", "-m", "manual target branch content") - git(repo, "push", "-u", "origin", "tsl-playbook") -``` - -- [ ] **Step 3: Assert preservation, cleanup, and idempotence** - -After the first `run_sync(repo)`, add: - -```python - for relative, expected in unmanaged_files.items(): - result = run( - ["git", "show", f"HEAD:{relative}"], - cwd=repo, - check=False, - ) - self.assertEqual(result.returncode, 0, msg=result.stderr) - self.assertEqual(result.stdout, expected) - - for relative in stale_managed_files: - result = run( - ["git", "cat-file", "-e", f"HEAD:{relative}"], - cwd=repo, - check=False, - ) - self.assertNotEqual(result.returncode, 0, msg=relative) - - first_publish = git(repo, "rev-parse", "HEAD").stdout.strip() - git(repo, "checkout", "main") - run_sync(repo) - second_publish = git(repo, "rev-parse", "HEAD").stdout.strip() - self.assertEqual(second_publish, first_publish) -``` - -Keep the existing assertions that generated `AGENTS.md`, `docs/tsl/index.md`, and both TSL Skill entrypoints exist. - -- [ ] **Step 4: Run the focused suite and verify RED** - -```powershell -python -B -m unittest discover -s test -p 'test_build_tsl_playbook.py' -v -``` - -Expected: FAIL because the current workflow has no `managed_paths` array and deletes the whole target `docs` and `skills` directories. - -- [ ] **Step 5: Define the exact managed paths in the workflow** - -Replace `generated_paths=(AGENTS.md docs skills)` with: - -```bash - managed_paths=( - "AGENTS.md" - "docs/tsl" - "skills/tsl-syntax-reference" - "skills/tsl-api-reference" - ) -``` - -Use it for pre-checkout validation: - -```bash - for path in "${managed_paths[@]}"; do - if [ ! -e "$bundle/$path" ]; then - echo "ERROR: bundle is missing expected path: $path" >&2 - exit 1 - fi - done -``` - -- [ ] **Step 6: Implement exact cleanup, copying, and staging** - -Replace the broad removal, bundle-root copy, and staging commands with: - -```bash - rm -rf -- "${managed_paths[@]}" - for path in "${managed_paths[@]}"; do - mkdir -p "$(dirname "$path")" - cp -R -- "$bundle/$path" "$path" - done - - git add -A -- "${managed_paths[@]}" -``` - -Do not add a `docs/tsl/syntax` condition or any other path exception. - -- [ ] **Step 7: Run the focused suite and verify GREEN** - -```powershell -python -B -m unittest discover -s test -p 'test_build_tsl_playbook.py' -v -``` - -Expected: all 7 tests pass. The integration test proves unmanaged root/docs/skills files survive, stale managed files disappear, and a second identical publication creates no commit. - -- [ ] **Step 8: Inspect and commit the implementation** - -```powershell -git diff --check -git diff -- .gitea/workflows/sync-tsl-playbook.yml test/test_build_tsl_playbook.py -git add .gitea/workflows/sync-tsl-playbook.yml test/test_build_tsl_playbook.py -git commit -m ':wrench: chore(ci): scope tsl playbook sync paths' -``` - -Expected: the commit contains only the workflow and its regression tests. - ---- - -### Task 2: Final workflow verification - -**Files:** -- Verify: `.gitea/workflows/sync-tsl-playbook.yml` -- Verify: `test/test_build_tsl_playbook.py` - -**Interfaces:** -- Consumes: Task 1's exact managed-path publication flow. -- Produces: fresh evidence that the workflow is scoped, secure, idempotent, and compatible with new target branches. - -- [ ] **Step 1: Run the full focused suite in a clean process** - -```powershell -python -B -m unittest discover -s test -p 'test_build_tsl_playbook.py' -v -``` - -Expected: 7 tests pass with `OK` and no errors or failures. - -- [ ] **Step 2: Verify the ownership contract directly** - -```powershell -rg -n 'managed_paths|generated_paths|rm -rf|cp -R|git add -A' .gitea/workflows/sync-tsl-playbook.yml -``` - -Expected: one four-entry `managed_paths` definition; no broad `generated_paths`; removal, copy, and staging derive from `managed_paths`; no whole-bundle copy. - -- [ ] **Step 3: Verify repository state** - -```powershell -git status --short -git show --stat --oneline HEAD -``` - -Expected: the implementation commit contains only `.gitea/workflows/sync-tsl-playbook.yml` and `test/test_build_tsl_playbook.py`, with a clean working tree. - -- [ ] **Step 4: Avoid a verification-only commit** - -If verification passes without corrections, stop. If it exposes a defect, return to Task 1's RED → GREEN cycle and commit only the correction: - -```powershell -git commit -m ':bug: fix(ci): close tsl playbook sync verification gap' -``` diff --git a/docs/superpowers/specs/2026-07-12-tsl-syntax-reference-logic-hardening-design.md b/docs/superpowers/specs/2026-07-12-tsl-syntax-reference-logic-hardening-design.md deleted file mode 100644 index 42ad9c7e..00000000 --- a/docs/superpowers/specs/2026-07-12-tsl-syntax-reference-logic-hardening-design.md +++ /dev/null @@ -1,194 +0,0 @@ -# TSL Syntax Reference 文档逻辑强化设计 - -## 背景 - -`tsl-syntax-reference` 已经形成清晰的单入口结构,但当前 `--query` 会直接返回整段正文。自然语言查询容易召回大节、输出数万字节,并把用户查询原样混入 Markdown。语法资料还会展示 API 调用,现有边界没有充分区分“语法外形示例”和“API 可用性事实”。 - -本设计选择破坏式升级,不保留旧查询输出协议。目标是让 Skill 默认采用“紧凑检索候选 → 精确取回章节”的两阶段流程,并把事实边界、自然语言映射和维护校验收紧为可测试契约。 - -## 目标 - -- `--query` 默认只输出紧凑候选,不再输出章节正文。 -- `--section` 是唯一正文取回入口。 -- 用户查询永远作为不可信数据转义,不得改变输出结构。 -- 改善中文口语、同义词、短 ASCII 关键字和混合查询的召回质量。 -- 索引 H2、H3、H4,使具体反例可精确取回。 -- Section ID 对符号标题稳定且无静默冲突。 -- 明确语法示例中的 API 调用不拥有 API 签名、环境 scope 或可用性事实。 -- 概念地图只表达自然语言职责,不输出链接、代码或可照写语法。 -- `--check` 覆盖每页职责、标题层级、Section ID、代码块身份和地图完整性。 -- 用 Python 和文档测试验证全部改动,不运行 TSL。 -- Skill 包不包含 `agents/openai.yaml` 等平台专用适配文件;通用发现元数据只写在 `SKILL.md` frontmatter。 - -## 非目标 - -- 不验证 TSL 示例能否编译或运行。 -- 不修改正在并发维护的 `tsl-api-reference` 资料、索引或 API 分类。 -- 不重写 24 篇参考资料的全部技术内容。 -- 不维持旧版 `--query` 的正文输出兼容性。 -- 不新增第三方搜索、分词或向量数据库依赖。 - -## 用户流程 - -### 自然语言起手 - -1. 用户需求尚未映射到 TSL 概念时,运行 `lookup.py --map`。 -2. 使用用户原始术语、错误文本和地图提示词执行 `lookup.py --query ... --mode ...`。 -3. 查询结果只列出候选的 Section ID、来源页、标题路径、分数、命中理由和短摘要。 -4. 选择支持当前结论的候选后,用 `lookup.py --section ` 取正文。 -5. 正文不足、版本不明、需要 API 或项目事实时停止并交接,不从其他语言或模型记忆补全。 - -### 混合意图 - -收到同时包含语法、API、命名、工具链或运行环境的请求时,先拆分事实所有者: - -- 语法外形、文件模型、表达式、控制流、对象和 TS-SQL 结构:本 Skill。 -- API 名称、签名、参数、返回值、平台 scope 与金融语义:`tsl-api-reference`。 -- 命名和风格:目标项目文档。 -- 执行命令、解释器和环境:最近的 `AGENTS.md`、项目脚本或 CI。 - -询问“如何运行”与实际执行 TSL 一样,必须读取最近的项目指引。不同所有者给出的事实不能直接拼接成“可运行”结论;API scope 与目标解释器兼容性缺失时必须停止。 - -## CLI 输出契约 - -### `--query` - -输出固定结构: - -```text -# TSL Syntax Candidates - -Mode: `write` -Query: "已转义的单行 JSON 字符串" - -## Candidate 1 -Score: 80 -Section ID: `...` -Source: `references/05_functions_and_calls.md` -Heading: `可直接照写示例 > 基础函数 / 过程骨架` -Why: `标题命中:函数;代码词命中:function` -Summary: 一行纯文本摘要。 -``` - -约束: - -- 不包含正文、代码围栏或绝对文件路径。 -- Query 使用 JSON 字符串编码,换行和控制字符不可生成 Markdown 结构。 -- 默认最多五个候选,仍允许 `--limit 1..10`。 -- 没有候选时 stderr 输出明确缺口并返回 2。 -- `write` 模式把两个必要前置章节作为候选置顶并标记 `Required: yes`,不展开正文。 - -### `--section` - -- 返回一个完整章节正文及逻辑来源路径。 -- 不接受 `--mode`。 -- 找不到时返回 2 并列出最相近的 Section ID。 - -### `--map` - -- 每个参考页恰好一条职责摘要。 -- 摘要必须是纯文本,不含 Markdown 链接、行内代码、代码围栏或可直接执行的完整语法。 -- 地图只帮助选择查询概念,不能作为生成代码的事实来源。 - -## 检索设计 - -### 分词与规范化 - -- 继续使用 Unicode NFKC 和大小写折叠。 -- ASCII 标识符按完整 token 匹配,不使用任意子串匹配;`if` 不得命中 `TIniFile` 或 `ifCache`。 -- 中文保留连续词和二元词,但过滤高频口语停用词。 -- 维护一个小型、显式、可测试的领域同义词表,例如: - - `打印`、`打出来` → `输出`、`writeLn` - - `左连接` → `左联接`、`left join` - - `列表` → `数组` - - `复用文件` → `.tsf`、`unit` - - `性能瓶颈` → `计时`、`profiler` -- 同义词只用于召回,不作为 TSL 事实输出。 - -### 索引粒度 - -- 建立 H2/H3/H4 层级栈,不再只索引 H2/H3。 -- H2/H3 聚合节仍可被检索,但候选优先选择更深、更具体的命中。 -- 同一页默认最多保留两个候选,避免五个名额被同一专题占满。 -- 标题精确命中、代码标识符命中、页标题命中和正文命中分别计分;输出实际排序所依据的总分。 - -### Section ID - -- 标题符号在 slug 前显式编码:`*`、`**`、`[]` 等得到不同稳定片段。 -- 同一页生成相同 ID 时,`--check` 直接失败,不再按出现顺序静默追加 `-2`。 -- ID 由相对页名和完整标题路径组成;来源只显示 `references/.md`。 - -## 事实边界 - -参考页可以在语法示例中使用 API 名称作为占位或观察手段,但必须遵守: - -- 示例只证明调用在该语法结构中的外形,不证明 API 的签名、返回值、平台 scope 或目标解释器可用性。 -- 需要依赖 API 结论时,答案必须重新查询 `tsl-api-reference`。 -- 参考页不得把 API 参数规格或平台分类声明为本 Skill 独占事实。 -- 输出、缓存、矩阵和运行时服务等现有交叉内容,通过 Skill 总边界和相关页面的局部说明统一澄清;本次不批量迁移 API 条目。 - -## SKILL.md 与发现元数据 - -- frontmatter 补充 `Tinysoft`、`天软`、`TS-SQL`、公式/策略脚本和常见语法报错触发词。 -- 不新增 OpenAI、Claude、Gemini 等平台专用元数据;各运行时直接读取通用 frontmatter。 -- 主流程只展示两阶段检索命令。 -- 增加安全传参要求:不得未经引用把用户文本拼进 shell。 -- 增加混合意图检查表和 API scope × 解释器兼容性阻断条件。 -- “执行 TSL 前读取项目指引”扩展为“询问或执行 TSL 运行方式时”。 -- 保留五种代码块身份,但明确“可直接照写”只描述源码外形,不等于目标环境验证通过。 - -## 校验设计 - -`--check` 新增以下失败条件: - -- 参考页缺少唯一 H1。 -- 参考页缺少且仅缺少一个非空 `## 本篇职责`。 -- 概念地图页数与参考页数不一致。 -- Section ID 冲突。 -- 标题层级从 H2/H3/H4 非法跳级。 -- 地图摘要包含 Markdown 链接、代码围栏或为空。 -- 查询前置章节锚点缺失。 - -现有代码块身份、围栏闭合、本地链接和人工路由协议检查继续保留。 - -## 测试策略 - -严格采用 RED → GREEN → REFACTOR,不运行 TSL。 - -### 查询与安全 - -- 查询中的换行、Markdown 标题、围栏和控制字符不能改变输出结构。 -- `--query` 输出不含章节正文、代码围栏或绝对路径。 -- `--section` 仍返回完整正文。 -- `if` 只命中独立关键字,不命中 `TIniFile`/`ifCache`。 -- “数据库左连接”召回 TS-SQL;“打出来”召回基础输出/函数示例。 - -### 自然语言矩阵 - -- 固化当前 24 条专题矩阵。 -- 最低门槛:Top-1 不低于 20/24,Top-5 为 24/24。 -- 对五个当前漏召回专题建立独立回归测试。 -- 增加混合意图、英文、错别字和 API 交接场景。 - -### 结构与文档 - -- 每页职责、H4 索引、符号 slug、ID 冲突和地图纯文本都有失败测试。 -- frontmatter 覆盖中英文发现关键词。 -- SKILL.md 必须明确两阶段检索、安全传参、事实边界和无 TSL 验证要求。 - -## 迁移与发布 - -- 这是明确的破坏式 CLI 变更;仓库内测试、评测说明和调用示例同步更新。 -- 不增加兼容开关、旧输出模式或弃用期。 -- 构建与安装流程继续复制同一 Skill 目录,不增加运行时依赖。 -- 验证命令仅包含 `lookup.py --check`、Python 单元/结构测试和相关构建/安装测试。 - -## 验收标准 - -- 所有新增测试先观察到预期失败,再由最小实现修复。 -- 24 条自然语言矩阵达到 Top-1 ≥ 20、Top-5 = 24。 -- 注入复现用例不再产生伪造 Markdown 标题或围栏。 -- 默认查询输出不超过 8KB,且不包含正文代码块。 -- 24 个参考页全部进入纯文本概念地图。 -- 目标 Skill、测试和路由文档通过 Python/文档校验。 -- 全程不运行 TSL,不修改 `tsl-api-reference` 文档树。 diff --git a/docs/superpowers/specs/2026-07-13-sync-tsl-playbook-workflow-upgrade-design.md b/docs/superpowers/specs/2026-07-13-sync-tsl-playbook-workflow-upgrade-design.md deleted file mode 100644 index d440a615..00000000 --- a/docs/superpowers/specs/2026-07-13-sync-tsl-playbook-workflow-upgrade-design.md +++ /dev/null @@ -1,116 +0,0 @@ -# Sync TSL Playbook Workflow Upgrade Design - -## Background - -The `tsl-playbook` branch is a mixed branch: the synchronization workflow owns the -generated TSL playbook paths, while README files and other manually maintained -content must survive each publication. - -The current workflow treats the whole `docs/` and `skills/` directories as generated: - -```bash -generated_paths=(AGENTS.md docs skills) -``` - -That ownership boundary is wider than the bundle actually owns. TSL syntax is now -provided by `tsl-syntax-reference`, while the branch may also contain unrelated -documentation and Skills that the workflow must not delete. - -## Goal - -Redesign `.gitea/workflows/sync-tsl-playbook.yml` so it updates only the TSL -playbook paths while preserving every unrelated target-branch file. - -## Managed Paths - -The workflow exclusively owns these four paths: - -```text -AGENTS.md -docs/tsl/ -skills/tsl-syntax-reference/ -skills/tsl-api-reference/ -``` - -It must preserve all other paths, including: - -- root files such as `README.md`; -- non-TSL documentation under `docs/`; -- unrelated Skills under `skills/`; -- any other manually maintained target-branch content. - -The workflow does not special-case `docs/tsl/syntax`. Whether that path exists is -determined by the source tree and the bundle builder, not by publication logic. - -## Publication Flow - -1. Clone and check out the latest `origin/main` in a temporary repository. -2. Build the TSL bundle outside the repository working tree. -3. Validate that all four managed paths exist in the bundle. -4. Check out the existing remote target branch, or create an orphan target branch. -5. Remove only the four managed paths from the target working tree. -6. Copy each managed path explicitly from the bundle. -7. Stage changes only for the four managed paths. -8. Exit successfully without a commit when the staged diff is empty. -9. Otherwise commit with the source SHA footer and push the target branch. - -Explicit copying is preferred over copying the bundle root. This keeps the workflow's -write behavior aligned with its declared ownership boundary even if the bundle gains -additional top-level files later. - -## Branch Behavior - -For an existing `tsl-playbook` branch, the workflow starts from -`origin/tsl-playbook`, so unmanaged files retain their current content and history. - -For a new target branch, the workflow creates an orphan branch and clears the inherited -index before adding the four managed paths. Source-only files from `main` must not leak -into the new branch. - -The workflow must not merge the source and target branches. It publishes a generated -commit directly on the target branch. - -## Failure Handling and Security - -- Missing bundle paths fail before the target branch is modified. -- `set -euo pipefail` remains enabled for shell steps. -- The bundle remains outside the repository so branch checkout cannot clobber it. -- Authentication continues through `GIT_ASKPASS`; credentials are never embedded in - the remote URL. -- Temporary bundle and askpass files are removed through existing cleanup paths. -- A failed copy or validation must prevent commit and push. - -## Test Strategy - -Update the workflow contract and integration tests before changing the workflow. - -The tests must demonstrate that: - -- the managed path list contains the four exact paths and not the broad `docs` or - `skills` directories; -- root files outside the managed set survive synchronization; -- non-TSL documentation under `docs/` survives synchronization; -- unrelated Skills under `skills/` survive synchronization; -- stale files inside each managed directory are deleted; -- a newly created target branch contains the bundle paths without source-branch - leakage; -- an unchanged bundle produces no commit; -- token handling remains based on `GIT_ASKPASS` and a credential-free repository URL. - -## Non-Goals - -- Do not change the contents of `AGENTS.md`, TSL documentation, or either TSL Skill. -- Do not add special handling for obsolete syntax-document paths. -- Do not redesign `scripts/build_tsl_playbook.py` unless a workflow test exposes an - interface mismatch required by the exact managed-path contract. -- Do not delete or rewrite unrelated files on the target branch. -- Do not change the target branch name or commit-message convention. - -## Acceptance Criteria - -- Publication changes are limited to the four managed paths. -- Unmanaged target-branch files are byte-for-byte preserved. -- Stale content inside managed paths is removed. -- New target branches contain no accidental files inherited from `main`. -- Existing workflow security assertions and sync integration tests pass. -- The full `test_build_tsl_playbook.py` suite passes.