| 1 | # One-off: migrate digest-engineering-reading-v1.md to kb-engineering-evidence-v1.md by knowledge theme. |
| 2 | # Run from knowledge/ folder. Reads digest, writes kb with entries grouped by theme (not batch). |
| 3 | # Batch -> theme mapping (by batch title and entry content): |
| 4 | BATCH_TO_THEME = { |
| 5 | "Batch 01": "Language and runtime", |
| 6 | "Batch 02": "Testing and diagnostics", |
| 7 | "Batch 03": "Async and reliability", |
| 8 | "Batch 04": "Platform and data layer", |
| 9 | "Batch 05": "Diagnostics and query efficiency", |
| 10 | "Batch 06": "Architecture and testing", |
| 11 | "Batch 07": "Data stores and resilience", |
| 12 | "Batch 08": "Architecture and fault isolation", |
| 13 | "Batch 09": "Algorithms, reliability, security", |
| 14 | "Batch 10": "Reliability and delivery", |
| 15 | "Batch 11": "Compilers and language tooling", |
| 16 | "Batch 12": "F# and interop", |
| 17 | "Batch 13": "OS and runtime environments", |
| 18 | "Batch 14": "Cloud, economics, scale", |
| 19 | } |
| 20 | |
| 21 | def parse_digest(path): |
| 22 | with open(path, "r", encoding="utf-8") as f: |
| 23 | text = f.read() |
| 24 | entries = [] |
| 25 | current_batch = None |
| 26 | current = None |
| 27 | for line in text.split("\n"): |
| 28 | if line.startswith("## Batch "): |
| 29 | # "## Batch 01 (Completed): Platform Baseline" -> "Batch 01" |
| 30 | part = line.split("(Completed)")[0].replace("## ", "").strip() |
| 31 | current_batch = part.split(":")[0].strip() if ":" in part else part |
| 32 | continue |
| 33 | if line.startswith("### Entry "): |
| 34 | if current and current.get("fact"): |
| 35 | current["batch"] = current_batch |
| 36 | entries.append(current) |
| 37 | num = line.replace("### Entry ", "").strip() |
| 38 | current = {"num": num, "source": "", "date": "", "fact": "", "heuristic": "", "first_adoption": "", "success": "", "confidence": ""} |
| 39 | continue |
| 40 | if not current: |
| 41 | continue |
| 42 | if line.startswith("- Source:"): |
| 43 | current["source"] = line.replace("- Source:", "").strip() |
| 44 | elif line.startswith("- Date:"): |
| 45 | current["date"] = line.replace("- Date:", "").strip() |
| 46 | elif line.startswith("- Fact:"): |
| 47 | current["fact"] = line.replace("- Fact:", "").strip() |
| 48 | elif line.startswith("- Heuristic:"): |
| 49 | current["heuristic"] = line.replace("- Heuristic:", "").strip() |
| 50 | elif line.startswith("- First adoption task:"): |
| 51 | current["first_adoption"] = line.replace("- First adoption task:", "").strip() |
| 52 | elif line.startswith("- Success criterion:"): |
| 53 | current["success"] = line.replace("- Success criterion:", "").strip() |
| 54 | elif line.startswith("- Confidence:"): |
| 55 | current["confidence"] = line.replace("- Confidence:", "").strip() |
| 56 | if current and current.get("fact"): |
| 57 | current["batch"] = current_batch |
| 58 | entries.append(current) |
| 59 | return entries |
| 60 | |
| 61 | def theme_of(entry): |
| 62 | return BATCH_TO_THEME.get(entry.get("batch", ""), "General") |
| 63 | |
| 64 | def main(): |
| 65 | import os |
| 66 | base = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # knowledge/ |
| 67 | world = os.path.join(base, "worlds", "software-engineering-evidence") |
| 68 | digest_path = os.path.join(world, "digest-engineering-reading-v1.md") |
| 69 | kb_path = os.path.join(world, "kb-engineering-evidence-v1.md") |
| 70 | |
| 71 | entries = parse_digest(digest_path) |
| 72 | by_theme = {} |
| 73 | for e in entries: |
| 74 | t = theme_of(e) |
| 75 | by_theme.setdefault(t, []).append(e) |
| 76 | |
| 77 | theme_order = [ |
| 78 | "Language and runtime", |
| 79 | "Testing and diagnostics", |
| 80 | "Async and reliability", |
| 81 | "Platform and data layer", |
| 82 | "Diagnostics and query efficiency", |
| 83 | "Architecture and testing", |
| 84 | "Data stores and resilience", |
| 85 | "Architecture and fault isolation", |
| 86 | "Algorithms, reliability, security", |
| 87 | "Reliability and delivery", |
| 88 | "Compilers and language tooling", |
| 89 | "F# and interop", |
| 90 | "OS and runtime environments", |
| 91 | "Cloud, economics, scale", |
| 92 | "General", |
| 93 | ] |
| 94 | |
| 95 | lines = [ |
| 96 | "# Engineering knowledge base (evidence) v1", |
| 97 | "", |
| 98 | "**Назначение:** база хранит знания, а не книги. Факты, эвристики и задачи внедрения с атрибуцией источника; источники — для цитирования и опционального углублённого чтения.", |
| 99 | "", |
| 100 | "**Формат записи:** Fact, Heuristic, First adoption task, Success criterion, Confidence; в конце — *Source* (и дата).", |
| 101 | "", |
| 102 | "---", |
| 103 | "", |
| 104 | ] |
| 105 | |
| 106 | for theme in theme_order: |
| 107 | if theme not in by_theme: |
| 108 | continue |
| 109 | block = by_theme[theme] |
| 110 | lines.append(f"## {theme}") |
| 111 | lines.append("") |
| 112 | for e in block: |
| 113 | lines.append(f"- **Fact:** {e['fact']}") |
| 114 | lines.append(f"- **Heuristic:** {e['heuristic']}") |
| 115 | lines.append(f"- **First adoption task:** {e['first_adoption']}") |
| 116 | lines.append(f"- **Success criterion:** {e['success']}") |
| 117 | lines.append(f"- **Confidence:** {e['confidence']}") |
| 118 | lines.append(f"- *Source:* {e['source']} ({e['date']})") |
| 119 | lines.append("") |
| 120 | lines.append("") |
| 121 | |
| 122 | with open(kb_path, "w", encoding="utf-8") as f: |
| 123 | f.write("\n".join(lines)) |
| 124 | |
| 125 | print(f"Wrote {kb_path} with {len(entries)} entries in {len(by_theme)} themes.") |
| 126 | |
| 127 | if __name__ == "__main__": |
| 128 | main() |
| 129 | |
| 130 | |