Repository navigation
Expand file tree
/
Copy pathbuild_punctim_dataset.py
More file actions
288 lines (230 loc) · 11.8 KB
/
Copy pathbuild_punctim_dataset.py
File metadata and controls
288 lines (230 loc) · 11.8 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
#!/usr/bin/env python3
"""Convert Punctim into a JSONL training dataset.
Modes:
wire — spec → codec implementation (teaches wire protocol)
adapter — spec + wire codec → adapter implementation (teaches adapter patterns)
certify — vectors + implementation → verification code (teaches certification)
Usage:
python build_punctim_dataset.py --mode wire --out wire_train.jsonl
python build_punctim_dataset.py --mode adapter --out adapter_train.jsonl
python build_punctim_dataset.py --mode certify --out certify_train.jsonl
"""
import argparse
import json
import sys
from pathlib import Path
REPO_ROOT = Path(__file__).parent
DOC_DIR = REPO_ROOT / "Documentation"
# ── Discovery ───────────────────────────────────────────────────────────────
CODEC_FILES = {
"C": REPO_ROOT / "codec" / "demod_frame.h",
"Rust": REPO_ROOT / "codec" / "src" / "lib.rs",
"Python": REPO_ROOT / "python" / "MCP" / "wirelab_core.py",
"Lua": REPO_ROOT / "GUI" / "wirelab.lua",
"Haskell": REPO_ROOT / "haskell" / "src" / "DCF" / "Transport" / "FrameSpec.hs",
"Lisp": REPO_ROOT / "lisp" / "src" / "wire.lisp",
}
ADAPTER_FILES = {
"audio": {
"spec": DOC_DIR / "DCF_AUDIO_SPEC.md",
"C": REPO_ROOT / "codec" / "demod_audio.c",
"Rust": REPO_ROOT / "codec" / "src" / "audio.rs",
"Python": REPO_ROOT / "python" / "MCP" / "audiolab_core.py",
"Lua": REPO_ROOT / "lua" / "dcf_audio.lua",
"vectors": DOC_DIR / "audio_vectors.json",
},
"game": {
"spec": DOC_DIR / "DCF_GAME_SPEC.md",
"C": REPO_ROOT / "codec" / "demod_game.c",
"Rust": REPO_ROOT / "codec" / "src" / "game.rs",
"Python": REPO_ROOT / "python" / "MCP" / "gamelab_core.py",
"vectors": DOC_DIR / "game_vectors.json",
},
"text": {
"spec": DOC_DIR / "DCF_TEXT_SPEC.md",
"Python": REPO_ROOT / "python" / "MCP" / "textlab_core.py",
"Rust": REPO_ROOT / "codec" / "src" / "text.rs",
"vectors": DOC_DIR / "text_vectors.json",
},
}
CERTIFY_FILES = {
"Python": REPO_ROOT / "python" / "MCP" / "verify_laws.py",
"Rust": REPO_ROOT / "codec" / "tests" / "certify.rs",
"C": REPO_ROOT / "C_SDK" / "tests" / "test_wire_certify.c",
}
def load_spec(path: Path) -> str | None:
if path.exists():
return path.read_text(encoding="utf-8")
return None
def load_code(path: Path) -> str | None:
if path.exists():
return path.read_text(encoding="utf-8")
return None
def load_vectors(path: Path) -> dict | None:
if path.exists():
return json.loads(path.read_text())
return None
def write_jsonl(records: list[dict], out: Path):
with out.open("w", encoding="utf-8") as f:
for rec in records:
f.write(json.dumps(rec, ensure_ascii=False) + "\n")
total_chars = sum(len(json.dumps(r, ensure_ascii=False)) for r in records)
avg_chars = total_chars // max(len(records), 1)
print(f"Wrote {len(records)} examples → {out}", file=sys.stderr)
print(f" total: {total_chars:,} chars | avg: {avg_chars:,} chars/line", file=sys.stderr)
# ── System prompts ──────────────────────────────────────────────────────────
SYSTEM_WIRE = """\
You are an expert DCF (DeMoD Communication Framework) wire protocol implementer. \
You write byte-certified codecs for the 17-byte DeModFrame across multiple languages.
THE WIRE QUANTUM:
- 17 bytes: sync(0xD3) | flags[ver|type] | seq | src | dst | payload(4B) | ts24 | crc16
- Version nibble = 1 (always)
- CRC-16/CCITT-FALSE over bytes [0..14], anchors: CRC("123456789")=0x29B1, CRC(0^15)=0x4EC3
- Valid iff sync byte + version nibble + CRC match
CONVENTIONS:
- Encode: take fields → pack into 17-byte buffer → compute CRC → write CRC at [15..16]
- Decode: verify sync + version + CRC → unpack fields → return struct or error
- All implementations MUST produce byte-identical output for identical input
- Use big-endian for multi-byte fields (network byte order)
- CRC polynomial: 0x1021, init: 0xFFFF, no final XOR
- Test against golden_vectors.json (246 vectors: 109 encode + 137 syndrome)
"""
SYSTEM_ADAPTER = """\
You are an expert DCF adapter implementer. You build protocols (audio, game, text, SSTV, snake, mesh) \
as adapters over the 17-byte DeModFrame wire quantum.
ADAPTER PATTERN:
- One adapter message → 1 + ceil(payload_len/4) DeModFrame packets
- seq = packet_id[15:5] | frag_idx[4:0] (for audio/game); text uses frag_idx[9:0]
- frag_idx 0 = descriptor: [len, frag_total, codec_id|msg_type_id, flags]
- Payload ≤ 124 B/block (4 bytes per frame × 31 frames max)
- L2 framing is codec/message-type-agnostic and byte-certified
- Adding new codecs/message types never changes the wire vectors
CONVENTIONS:
- Encode: serialize payload → fragment into ≤124B chunks → wrap each in DeModFrame
- Decode: collect frames by packet_id → reassemble payload → validate CRC per frame
- Use CTRL (type 3) frames for audio; DATA (type 0) frames for game/text/SSTV
- Descriptor flags: bit0 RELIABLE, bit1 ORDERED, bit2 END_TICK (adapter-specific)
"""
SYSTEM_CERTIFY = """\
You are an expert DCF certification engineer. You write verification code that ensures \
cross-language byte-identical behavior of DCF codecs and adapters.
CERTIFICATION PATTERN:
- Golden vectors: JSON array of {input, expected_output} test cases
- Encode vectors: input fields → expected 17-byte buffer
- Syndrome vectors: input buffer → expected decoded fields or error
- All languages must pass all 246 vectors (109 encode + 137 syndrome)
- Regenerate vectors from reference (Python), diff against committed
CONVENTIONS:
- Load vectors from Documentation/golden_vectors.json (or audio_vectors.json, etc.)
- For each vector: encode/decode with your implementation → compare to expected
- Print PASS/FAIL per vector, exit non-zero on any failure
- Use exact byte comparison (no floating-point tolerance)
- CI runs on every push/PR to main
"""
# ── Mode: wire ──────────────────────────────────────────────────────────────
def build_wire_examples() -> list[dict]:
records = []
spec = load_spec(DOC_DIR / "WIRE_QUANTUM_SPEC.md")
vectors = load_vectors(DOC_DIR / "golden_vectors.json")
if not spec:
print("Warning: WIRE_QUANTUM_SPEC.md not found", file=sys.stderr)
return records
for lang, path in CODEC_FILES.items():
code = load_code(path)
if not code:
continue
user_parts = [
f"Implement the DCF wire codec in {lang}.",
f"\nSpecification:\n{spec}",
]
if vectors:
sample = {
"encode_basis": vectors.get("encode_basis", [])[:10],
"syndrome_basis": vectors.get("syndrome_basis", [])[:10],
}
user_parts.append(f"\nGolden vectors (sample):\n{json.dumps(sample, indent=2)}")
user_parts.append("\nProvide the complete implementation with encode/decode functions.")
records.append({"messages": [
{"role": "system", "content": SYSTEM_WIRE},
{"role": "user", "content": "\n".join(user_parts)},
{"role": "assistant", "content": code},
]})
return records
# ── Mode: adapter ───────────────────────────────────────────────────────────
def build_adapter_examples() -> list[dict]:
records = []
wire_spec = load_spec(DOC_DIR / "WIRE_QUANTUM_SPEC.md")
for adapter_name, files in ADAPTER_FILES.items():
spec = load_spec(files["spec"])
if not spec:
continue
vectors_path = files.get("vectors")
vectors = load_vectors(vectors_path) if vectors_path else None
for lang, path in files.items():
if lang in ("spec", "vectors"):
continue
code = load_code(path)
if not code:
continue
user_parts = [
f"Implement the DCF {adapter_name} adapter in {lang}.",
]
if wire_spec:
user_parts.append(f"\nWire quantum spec (for context):\n{wire_spec[:2000]}...")
user_parts.append(f"\nAdapter specification:\n{spec}")
if vectors:
sample = {
"encode_basis": vectors.get("encode_basis", [])[:5],
"syndrome_basis": vectors.get("syndrome_basis", [])[:5],
}
user_parts.append(f"\nGolden vectors (sample):\n{json.dumps(sample, indent=2)}")
user_parts.append("\nProvide the complete implementation with encode/decode functions.")
records.append({"messages": [
{"role": "system", "content": SYSTEM_ADAPTER},
{"role": "user", "content": "\n".join(user_parts)},
{"role": "assistant", "content": code},
]})
return records
# ── Mode: certify ───────────────────────────────────────────────────────────
def build_certify_examples() -> list[dict]:
records = []
vectors = load_vectors(DOC_DIR / "golden_vectors.json")
if not vectors:
print("Warning: golden_vectors.json not found", file=sys.stderr)
return records
for lang, path in CERTIFY_FILES.items():
code = load_code(path)
if not code:
continue
user_parts = [
f"Write certification/verification code in {lang} for the DCF wire codec.",
f"\nGolden vectors (sample):\n{json.dumps({'encode_basis': vectors.get('encode_basis', [])[:20], 'syndrome_basis': vectors.get('syndrome_basis', [])[:20]}, indent=2)}",
"\nThe code should:",
"1. Load the vectors from a JSON file",
"2. For each encode vector: encode the input fields → compare to expected buffer",
"3. For each syndrome vector: decode the input buffer → compare to expected fields",
"4. Print PASS/FAIL per vector, exit non-zero on any failure",
"\nProvide the complete implementation.",
]
records.append({"messages": [
{"role": "system", "content": SYSTEM_CERTIFY},
{"role": "user", "content": "\n".join(user_parts)},
{"role": "assistant", "content": code},
]})
return records
# ── CLI ─────────────────────────────────────────────────────────────────────
def main():
ap = argparse.ArgumentParser(description="Build JSONL training dataset from Punctim")
ap.add_argument("--mode", choices=["wire", "adapter", "certify"], default="wire")
ap.add_argument("--out", type=Path, default=Path("punctim_train.jsonl"))
ap.add_argument("--min-chars", type=int, default=0, help="Skip examples where assistant content < N chars")
args = ap.parse_args()
builders = {"wire": build_wire_examples, "adapter": build_adapter_examples, "certify": build_certify_examples}
records = builders[args.mode]()
if args.min_chars:
before = len(records)
records = [r for r in records if len(r["messages"][-1]["content"]) >= args.min_chars]
print(f"Filtered {before - len(records)} examples < {args.min_chars} chars", file=sys.stderr)
write_jsonl(records, args.out)
if __name__ == "__main__":
main()