main
py 100 lines 3.25 KB
Raw
1 #!/usr/bin/env python3
2 """Initialize per-topic learning state directories with seeded wisdom."""
3
4 import argparse
5 import sys
6 from pathlib import Path
7
8 import yaml
9
10 SQUAD_DIR = Path(".squad")
11
12 SEEDED_WISDOM = {
13 "ai-ml": """\
14 # AI & Machine Learning Topic Wisdom
15
16 ## Signal Patterns
17 - Papers with code implementations gain rapid adoption
18 - Framework-adjacent tools (PyTorch/TensorFlow ecosystem) show sustained growth
19 - LLM-related repos have high initial stars but variable retention
20 - Research reproducibility repos (paper implementations) peak early then plateau
21
22 ## Noise Patterns
23 - Tutorial/course repos with high stars but low forks are often one-time views
24 - Wrapper libraries around APIs tend to be ephemeral
25 - Repos that only add a README without substantial code are often hype-driven
26
27 ## Scoring Adjustments
28 - Weight Python and Jupyter Notebook repos higher
29 - Look for arXiv references as quality signals
30 - Multi-language repos (Python + C++) often indicate serious frameworks
31 """,
32 "rust": """\
33 # Rust Topic Wisdom
34
35 ## Signal Patterns
36 - CLI tools that replace existing Unix utilities gain rapid adoption
37 - Async runtime ecosystem tools show sustained growth
38 - WebAssembly-targeting Rust projects are emerging strongly
39 - Safety-focused alternatives to C/C++ libraries gain institutional backing
40
41 ## Noise Patterns
42 - "Rewrite in Rust" repos without clear improvements over originals
43 - Learning projects with "rust-" prefix but minimal functionality
44 - Abandoned experimental repos from Rust newcomers
45
46 ## Scoring Adjustments
47 - Weight Rust language repos exclusively
48 - Cross-compilation and no_std support indicate maturity
49 - Cargo ecosystem integration (published crate) is a strong signal
50 """,
51 }
52
53
54 def init_topic(topic_id: str, *, force: bool = False, base_dir: Path | None = None) -> Path:
55 """Create learning state directory structure for a topic.
56
57 Returns the created topic directory path.
58 """
59 root = (base_dir or SQUAD_DIR) / "topics" / topic_id
60 skills_dir = root / "skills"
61 scorecards_dir = root / "scorecards"
62 wisdom_file = root / "wisdom.md"
63
64 # Create directories
65 skills_dir.mkdir(parents=True, exist_ok=True)
66 scorecards_dir.mkdir(parents=True, exist_ok=True)
67
68 # Seed wisdom
69 if force or not wisdom_file.exists():
70 content = SEEDED_WISDOM.get(topic_id, f"# {topic_id} Topic Wisdom\n")
71 wisdom_file.write_text(content)
72
73 return root
74
75
76 def topic_id_from_config(config_path: str) -> str:
77 """Read topic.id from a YAML config file."""
78 with open(config_path) as f:
79 data = yaml.safe_load(f)
80 return data["topic"]["id"]
81
82
83 def main(argv: list[str] | None = None) -> None:
84 parser = argparse.ArgumentParser(description="Initialize per-topic learning state")
85 parser.add_argument("--topic", help="Topic ID to initialize")
86 parser.add_argument("--config", help="Path to topic YAML config (reads topic.id)")
87 parser.add_argument("--force", action="store_true", help="Overwrite existing wisdom")
88
89 args = parser.parse_args(argv)
90
91 if not args.topic and not args.config:
92 parser.error("Provide --topic or --config")
93
94 topic_id = args.topic or topic_id_from_config(args.config)
95 root = init_topic(topic_id, force=args.force)
96 print(f"Initialized learning state: {root}")
97
98
99 if __name__ == "__main__":
100 main()