packet-tracer-skill 0.2.2 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/CHANGELOG.md +424 -42
  2. package/README.md +535 -250
  3. package/SKILL.md +337 -262
  4. package/bin/packet-tracer-skill.js +29 -2
  5. package/docs/automation-controller-proof.md +35 -0
  6. package/docs/curated-donor-registry.md +11 -0
  7. package/docs/generate-ready-pilot-design.md +30 -0
  8. package/docs/github-launch-ops-0.2.3.md +37 -0
  9. package/docs/github-metadata.md +6 -4
  10. package/docs/hero-demo-plan.md +1 -1
  11. package/docs/home-iot-donor-proof.md +4 -4
  12. package/docs/industrial-programming-proof.md +48 -0
  13. package/docs/ipv4-routing-management-proof.md +37 -0
  14. package/docs/l2-resiliency-bgp-proof.md +60 -0
  15. package/docs/l2-security-qos-proof.md +59 -0
  16. package/docs/packet-tracer-feature-gap-atlas.md +174 -17
  17. package/docs/post-launch-follow-up.md +9 -5
  18. package/docs/proof-readiness-dashboard.md +69 -0
  19. package/docs/publish-preview-roadmap.md +6 -5
  20. package/docs/release-checklist.md +27 -13
  21. package/docs/release-notes-0.2.2.md +1 -1
  22. package/docs/release-notes-0.2.3.md +59 -0
  23. package/docs/release-notes-0.2.4.md +20 -0
  24. package/docs/runtime-truth.md +33 -8
  25. package/docs/security-edge-deepening-proof.md +65 -0
  26. package/docs/voice-collaboration-proof.md +38 -0
  27. package/docs/wan-security-donor-proof.md +20 -3
  28. package/examples/README.md +98 -69
  29. package/examples/complex_campus_master_edit_v4.inventory.json +12 -2
  30. package/examples/gallery.md +94 -6
  31. package/examples/home_iot_cli_edit_v1.inventory.json +11 -2
  32. package/examples/index.json +932 -4
  33. package/examples/local-sample-evidence.json +24 -0
  34. package/examples/proof-cards.json +117 -0
  35. package/examples/service_heavy_cli_edit_v1.inventory.json +11 -2
  36. package/package.json +60 -44
  37. package/pytest.ini +9 -0
  38. package/references/packettracer-feature-atlas.json +67 -17
  39. package/references/packettracer-sample-catalog.json +45287 -4525
  40. package/references/packettracer-sample-catalog.md +599 -259
  41. package/references/proof-readiness-candidates.json +352 -0
  42. package/scripts/build_examples_index.py +228 -35
  43. package/scripts/build_sample_catalog.py +24 -44
  44. package/scripts/corpus_runner.py +430 -0
  45. package/scripts/coverage_matrix.py +1842 -1319
  46. package/scripts/donor_cache.py +354 -0
  47. package/scripts/donor_diagnostics.py +3 -1
  48. package/scripts/feature_atlas.py +65 -1
  49. package/scripts/generate_pkt.py +8762 -4070
  50. package/scripts/intent_parser.py +2242 -1138
  51. package/scripts/local_donors.py +340 -0
  52. package/scripts/packet_tracer_env.py +846 -391
  53. package/scripts/pkt_annotate.py +218 -0
  54. package/scripts/pkt_codec.py +420 -181
  55. package/scripts/pkt_editor.py +2405 -1226
  56. package/scripts/pkt_transformer.py +1072 -727
  57. package/scripts/pkt_verify.py +461 -0
  58. package/scripts/remote_search.py +197 -21
  59. package/scripts/runtime_doctor.py +80 -29
  60. package/scripts/sample_catalog.py +1372 -1195
  61. package/scripts/twofish_diagnostics.py +48 -31
  62. package/scripts/usage_ledger.py +218 -0
  63. package/scripts/vendor/README.md +44 -37
  64. package/scripts/vendor/twofish_pure.py +321 -0
  65. package/scripts/workspace_repair.py +548 -508
  66. package/templates/pt900/donors/README.md +15 -0
package/CHANGELOG.md CHANGED
@@ -2,47 +2,429 @@
2
2
 
3
3
  All notable changes to this project should be recorded in this file.
4
4
 
5
- The format is intentionally simple and release-oriented.
6
-
7
- ## [0.2.2]
8
-
9
- ### Added
10
-
11
- - advanced wireless proof surface for WEP and WPA Enterprise/RADIUS edit-proven behavior
12
- - wireless advanced feature atlas coverage for WLC, Meraki, cellular, Bluetooth, beamforming, guest Wi-Fi, WEP, and WPA Enterprise
13
- - runtime README guidance for generic Twofish bridge paths and search-root fallback
14
-
15
- ### Changed
16
-
17
- - package version advanced to `0.2.2` for the README/runtime cleanup and advanced wireless feature wave
18
- - README runtime setup no longer presents a user-specific `.codex` path as the default bridge location
19
- - advanced wireless prompts now classify into the `wireless_advanced` family without drifting into `service_heavy`
20
- - WEP and WPA Enterprise/RADIUS are represented as edit-proven where explicit deterministic edit targets exist, while broader WLC/cellular/Bluetooth/Meraki scope remains report-only
21
-
22
- ### Notes
23
-
24
- - `0.2.2` remains conservative: no broad synthetic advanced wireless generation is claimed
25
- - runtime messaging remains Windows-first and explicit about external bridge-assisted validation
26
-
27
- ## [0.2.1]
28
-
29
- ### Added
30
-
31
- - npm tarball hardening for the public package surface
32
- - launch announcement draft aligned with the current public release wording
33
-
34
- ### Changed
35
-
36
- - package version advanced to `0.2.1` because `0.2.0` is already published on npm
37
- - npm package contents now exclude caches, generated previews, and non-essential screenshot payloads
38
- - public release references now consistently point to the `0.2.1` patch release artifacts
39
-
40
- ### Notes
41
-
42
- - `0.2.1` is the publishable patch release for the conservative public preview surface
43
- - runtime messaging remains Windows-first and explicit about the external bridge-assisted validation path
44
-
45
- ## [0.2.0]
5
+ The format is intentionally simple and release-oriented.
6
+
7
+ ## [0.3.0] - 2026-08-06
8
+
9
+ ### First verified generation
10
+
11
+ A prompt now produces a `.pkt` that Packet Tracer actually opens. Confirmed on
12
+ 2026-08-02: `1 router 1 switch ve 3 komputer qur` produced a `9.0.0.0810` file
13
+ containing exactly `R1 <-> SW1` and `SW1 <-> PC1/PC2/PC3`, and Packet Tracer
14
+ loaded it in 40 seconds with the window title naming the file.
15
+
16
+ ### Added
17
+
18
+ - `scripts/pkt_verify.py`: two-tier verification. `structural_check` is headless
19
+ and catches dangling link endpoints, duplicate device names, undecodable
20
+ bytes, wrong root elements and incompatible versions. `open_check` launches
21
+ Packet Tracer and waits for the file's own window, reporting
22
+ `opened` / `timeout` / `process_exited` / `packet_tracer_missing`.
23
+ - `scripts/usage_ledger.py`: a local, gitignored record of which donors actually
24
+ worked, fed back into donor ranking so repeat requests try proven donors
25
+ first. Prompts are stored as a non-reversible fingerprint, never verbatim.
26
+ Bounded to 2000 entries, disabled with `PKT_USAGE_LEDGER=off`, and never
27
+ load-bearing — deleting it changes nothing but donor order.
28
+ - `tests/test_pkt_verify.py`, `tests/test_usage_ledger.py`,
29
+ `tests/test_donor_grouping.py`.
30
+
31
+ ### Changed limitations removed
32
+
33
+ - **The target version is detected, not hardcoded.** Resolution order:
34
+ `PACKET_TRACER_TARGET_VERSION`, the installed Packet Tracer's directory name,
35
+ the compatibility donor's `<VERSION>`, then the default. An 8.2 install now
36
+ targets 8.2 with no configuration. The install-root name yields a three-field
37
+ version deliberately, so a bundled sample carrying `9.0.0.0000` cannot
38
+ outrank the user's own saves by matching a build number that was invented.
39
+ - **The Windows-only restriction is gone.** It existed because the codec needed
40
+ a compiled bridge only ever built for Windows; the pure-Python engine removed
41
+ that. `windows_first_runtime` is no longer raised, and a missing Packet Tracer
42
+ executable is reported as exactly that.
43
+ - **Pruning is no longer an unsafe mutation.** `remove_link` was categorised as
44
+ `port_reassignment` and, with `device_prune`, sat on the blocked list — so the
45
+ safe-open profile forbade the two core operations of donor-prune generation.
46
+ `remove_link` is now `link_prune`, and prune operations are allowed. Inventing
47
+ structure the donor never had stays blocked.
48
+ - **The sample catalogue is version-gated.** Only the compatibility donor was
49
+ checked before, so a 9.0-targeted run could select a 6.1 sample and emit a 6.1
50
+ file. Observed and fixed.
51
+ - Donor groups are aligned to targets by router uplink instead of name order. A
52
+ donor containing `Router <-> Switch` on its second switch was previously
53
+ reported as not containing that link at all.
54
+ - `validate_open` verifies instead of announcing. It ran `subprocess.Popen` and
55
+ printed `{"status": "launched"}` without observing anything, so a corrupt file
56
+ reported the same result as a working one.
57
+ - `validate_external_sample_summary` uses the compatibility ladder rather than
58
+ string equality.
59
+ - Python minimum is 3.10; the 3.14 pin applied only to the optional accelerator.
60
+
61
+ ### Performance
62
+
63
+ Generation went from 200-250 s to **94 s** for a small lab. Profiling showed 340
64
+ of 349 seconds inside `decode_pkt_modern`, and 69 of the 82 calls came from
65
+ `_pkt_version` — full authenticated decrypts of entire multi-megabyte files
66
+ performed only to read `<VERSION>`.
67
+
68
+ - `pkt_codec.peek_pkt_header` decrypts only the front of a file. CTR mode is
69
+ seekable and stage 1 reverses the buffer, so the needed plaintext prefix comes
70
+ from the file's tail: the probe is now O(prefix), not O(file). Measured
71
+ constant ~21 ms regardless of size, against 14.8 s for a full decode of the
72
+ largest lab — 679x on that file, and byte-identical version strings.
73
+ Tag verification is deliberately skipped; this is a read-only probe and
74
+ anything that matters still goes through `decode_pkt_modern`.
75
+ - `_pkt_version` and `decode_pkt_to_root` cache on `(path, size, mtime_ns)`, so
76
+ an edited file is re-read rather than served stale. Only immutable bytes are
77
+ cached; callers still get their own tree to mutate.
78
+
79
+ ### Every corpus case now opens in Packet Tracer
80
+
81
+ 7 generated, 7 opened, 1 correctly refused, 0 unexpected — including topologies
82
+ larger than the donor itself.
83
+
84
+ **The cause of every "not compatible with this version" rejection was invented
85
+ `*_MEM_ADDR` values on newly created links.** Rebuilding an existing, working
86
+ host link with the same devices and ports left exactly five fields different
87
+ from the original: `LENGTH` and the four MEM_ADDRs. Omitting those four makes
88
+ the same link open. They are runtime pointers from the session that saved the
89
+ file — in working donors they resolve to no device at all.
90
+
91
+ That single finding retired an earlier conclusion. Created `Pc <-> Switch` links
92
+ had been refused on the theory that host connections could not be built; the
93
+ endpoint kind was incidental, the invented pointers were the cause.
94
+ `_ensure_link` no longer writes them on a new link, and the restriction is gone.
95
+ The repo's own workspace validator required them too, and so rejected files
96
+ Packet Tracer accepts; it now objects only when one end has a reference and the
97
+ other does not.
98
+
99
+ With that unblocked, three duplication operations close the remaining gaps —
100
+ `duplicate_device`, `duplicate_group`, and `duplicate_host` — each verified
101
+ against a real open. All three must run **after** the rename and prune pass,
102
+ from devices already carrying their final names; emitting them first and
103
+ renaming the copies afterwards produces files Packet Tracer refuses.
104
+
105
+ The donor now constrains which device models are available, not how large a
106
+ topology can be.
107
+
108
+ ### First open-verified generation set, and what it disproved
109
+
110
+ Running the corpus with real Packet Tracer opens produced the first evidence-backed
111
+ readiness numbers — and immediately contradicted two things this repo believed.
112
+
113
+ **Cross-group device borrowing does not work.** A target switch needing more
114
+ hosts than its aligned donor switch carries was allowed to borrow from other
115
+ donor groups. Every corpus case that borrowed failed to open (4, 5 and 7 hosts);
116
+ every case that stayed within its donor group's own hosts opened (2 and 3).
117
+ Moving a device between switch groups leaves state this code does not fix up.
118
+ Borrowing is off by default now; `PACKET_TRACER_CROSS_GROUP_BORROW=1` re-enables
119
+ it for experiments. A refusal beats a file that looks generated and will not open.
120
+
121
+ **Coverage reporting is not base-donor eligibility.** The version policy was
122
+ applied to `_existing_ranked_candidates`, which feeds both. Under the `exact`
123
+ default every bundled sample vanished and campus prompts started refusing with
124
+ "critical capability coverage is still missing" — for coverage sitting in the
125
+ catalogue all along. A sample proves a capability whether or not it can serve as
126
+ a generation base, so the policy now applies only in `_base_donor_candidates`.
127
+ Generation also got 4x faster as a side effect: 6-7 s per case instead of 24-50 s,
128
+ because the base pool is small while coverage still sees everything.
129
+
130
+ Refusal messages no longer suggest loosening the donor policy. Loosening was
131
+ measured to produce files Packet Tracer refuses, so the advice walked users into
132
+ a broken state that looked like progress. When the running build is unknown the
133
+ message asks for the one action that helps: save any lab from Packet Tracer once,
134
+ which is what teaches the skill its build.
135
+
136
+ Corpus now: **4 generate and open, 3 donor-limited, 1 correct refusal, 0
137
+ unexpected.** `refused_donor_limited` is a distinct status so a sound request the
138
+ local donor cannot serve stays countable without being mistaken for a defect.
139
+
140
+ ### A corpus runner, and the five defects it found immediately
141
+
142
+ `scripts/corpus_runner.py` runs a set of prompts end to end and records what
143
+ happened: generated or refused, structural result, and optionally a real Packet
144
+ Tracer open. Its first run found five defects that 377 unit tests had not.
145
+
146
+ - **Device counts attached to the wrong device.** Two phrasings are supported,
147
+ `3 switch` and `switch 3`, and both were pooled through `max`. The trailing
148
+ form swallowed the next device's number, so `4 switch 1 router 8 komputer`
149
+ asked for **eight routers** and `1 router 1 switch 2 komputer` asked for two
150
+ switches. No test had ever asserted a multi-device count.
151
+ - **A prompt with no topology signal produced a lab.** "sebeke haqqinda melumat
152
+ ver" — a request for information — generated a two-device file. Inventing a
153
+ lab is worse than refusing: the user never sees that they were misread.
154
+ - **Host capacity was checked per donor switch group** rather than across the
155
+ donor, so "1 switch and 5 PCs" was refused against a donor holding 11 PCs on
156
+ three switches, every one of which was about to be pruned. Donor devices are
157
+ pooled across groups now.
158
+ - **Two cables on one interface.** Ports are set from two independent places:
159
+ surviving donor links keep their wiring, and `set_link` operations carry
160
+ planner-chosen ports. Neither knew about the other, so `PC1` and `R1` both
161
+ landed on `SW1 FastEthernet0/3`. `_resolve_port_conflicts` reconciles once
162
+ over the links that will actually exist; surviving donor wiring wins because
163
+ it is known-good.
164
+ - **Group alignment dropped donors.** With more targets than donor groups the
165
+ reordering lost entries, and the caller then reported "supports only 0 switch
166
+ groups" for a donor with three switches.
167
+
168
+ Refusals also name the layer that failed. When the intent plan has gaps, donor
169
+ evaluation never runs, so reporting "donor selection" with zero candidate counts
170
+ sent users to fix a donor that had never been consulted. That is
171
+ `blocked_by_intent` now, and donor messages name the donor.
172
+
173
+ Corpus: **6 of 8 generate, 1 refuses correctly, 1 known gap.** `four_switch`
174
+ needs a donor with four switch groups; none of the eligible donors has one, so
175
+ the refusal is real. Generation also got faster — the inflated device counts had
176
+ been driving much larger donor searches, and the minimal case went from 103 s to
177
+ 24 s.
178
+
179
+ ### Every bundled sample is readable now
180
+
181
+ 18 of the 292 samples shipped with Packet Tracer 9.0 failed EAX tag
182
+ verification and were reported as undecodable. They are Packet Tracer 5.x
183
+ saves written before Twofish: qCompress output XORed byte-wise with
184
+ `(length - index)`, no cipher and no tag. `decode_pkt_legacy`,
185
+ `detect_pkt_format` and `decode_pkt_auto` handle both containers.
186
+
187
+ A further 6 decoded but would not parse. Packet Tracer writes raw control bytes
188
+ into element text — a Cisco banner delimiter is literally `banner motd ` —
189
+ which XML 1.0 forbids. `parse_pkt_xml` maps those into the Unicode private use
190
+ area and `serialize_pkt_xml` maps them back, so the round trip stays faithful
191
+ instead of silently dropping banner delimiters.
192
+
193
+ `build_sample_catalog.py` carried its own weaker `summarize_pkt` that omitted
194
+ link endpoints, which is why the committed catalogue had 1051 link records with
195
+ no `from`/`to` and the donor graph-fit filter was comparing empty strings. It
196
+ now calls `sample_catalog._summarize_pkt`.
197
+
198
+ Catalogue rebuild: **292 of 292 readable** (was 274) and **1126 links with
199
+ endpoints** (was 0). Reading those labs promoted `qos`, `cbac`, `real_http` and
200
+ `real_websocket` from report/edit level to `donor_backed_ready`. Those
201
+ capabilities were never missing — the labs proving them were unreadable.
202
+
203
+ ### Topologies are no longer limited to the donor's own
204
+
205
+ Reuse-only wiring meant a chain donor could never satisfy a star request:
206
+ `3 switch, 6 PC, VLAN 10/20/30` was refused with "this donor does not contain
207
+ that device-to-device link". Missing links are now built with the same
208
+ `set_link` operation the edit path uses (`PACKET_TRACER_LINK_STRATEGY=reuse`
209
+ restores the old behaviour).
210
+
211
+ This needed three fixes, and the first attempt was rejected by Packet Tracer
212
+ outright — the two-tier verification caught it as `process_exited` rather than
213
+ reporting a false success:
214
+
215
+ - ports are claimed once. Adopting donor wiring for one link while planning
216
+ another from the blueprint put two cables on `SW1 GigabitEthernet0/2`.
217
+ - alternatives are checked against the device's real interfaces. Incrementing
218
+ the index invented `GigabitEthernet0/3` on a 2960-24TT, and Packet Tracer
219
+ refused the whole file as "not compatible with this version".
220
+ - when gigabit is exhausted the allocator falls back to FastEthernet, which is
221
+ what an engineer would do. A core switch with three uplinks and two gigabit
222
+ ports is a real constraint, not an impossible topology.
223
+
224
+ `port_exists` and `port_capacity` count real interfaces. `_port_address_for_name`
225
+ could not serve as the existence test: it is a MEM_ADDR lookup that returns
226
+ None whenever the donor's port nodes carry no address, which made every port
227
+ look missing.
228
+
229
+ Verified: 3-switch VLAN star on a chain donor opened in 10.1 s; the simple case
230
+ still opens in 10.4 s. `structural_check` now also fails on duplicate port use.
231
+
232
+ ### Host-to-VLAN distribution is defaulted, not refused
233
+
234
+ "3 switch, 6 PC, VLAN 10/20/30" reads as two hosts per VLAN. The planner refused
235
+ it while already defaulting port speeds, cable types, addressing and the VLAN IDs
236
+ themselves — and while the branch directly above already assigned department PCs
237
+ to VLANs by order. Hosts are now spread evenly with the split recorded as an
238
+ assumption. `PACKET_TRACER_STRICT_VLAN_ASSIGNMENT=1` restores the refusal.
239
+
240
+ The rule existed in both `intent_parser` and `generate_pkt`; it now lives only in
241
+ the parser.
242
+
243
+ ### Leftover donor devices are now deleted
244
+
245
+ Spares were renamed `UNUSED-*` / `*-SPARE-*` and moved offscreen rather than
246
+ deleted, so a five-device request produced a twenty-device, 282 KB file. Parking
247
+ was a precaution, not a measured constraint — and with real verification in place
248
+ it could finally be tested instead of assumed.
249
+
250
+ Pruning verified against a real Packet Tracer open: **6 devices, 73 KB, opened in
251
+ 17 s** (the parked equivalent took 40 s). `prune` is now the default;
252
+ `PACKET_TRACER_SPARE_STRATEGY=park` restores the old behaviour.
253
+
254
+ ## [0.3.0-pre] - Runtime and donor gate
255
+
256
+ Removes the two mechanical defects that produced `generate_ready=0` for the
257
+ whole `0.2.x` line. See `docs/improvement-plan-0.3.0.md` for the audit.
258
+
259
+ ### Added
260
+
261
+ - `scripts/vendor/twofish_pure.py`: vendored pure-Python Twofish, verified
262
+ against the official 128/192/256-bit test vectors and cross-checked as
263
+ bit-identical to the compiled bridge
264
+ - donor version compatibility ladder in `packet_tracer_env.py`
265
+ (`exact` / `same_minor` / `same_major` / `upgradeable` / `incompatible`),
266
+ selected by `PACKET_TRACER_DONOR_POLICY`, defaulting to `same_minor`
267
+ - `twofish_backend`, `donor_policy`, and `compatibility_tier` diagnostic fields
268
+ - `tests/test_twofish_pure.py` and `tests/test_donor_compatibility.py`
269
+
270
+ ### Changed
271
+
272
+ - the compiled `_twofish` bridge is now an optional accelerator, not a
273
+ prerequisite: `decode`, `inventory`, `edit`, and `generate` are all `ready` on
274
+ a clean checkout with no binaries and no environment variables
275
+ - `bridge_resolution=external_env` no longer downgrades `runtime_grade` or
276
+ raises a `using_external_bridge_only` blocker
277
+ - donor rejection messages now name the tier, the active policy, and the setting
278
+ that would accept the donor
279
+ - minimum Python relaxed from exactly 3.14 to 3.10+; the 3.14 ABI requirement
280
+ applied only to the compiled accelerator
281
+
282
+ ### Fixed
283
+
284
+ - `tests/test_release_surface.py` referenced an undefined `readme` variable and
285
+ failed under the strict profile; the assertions moved to the README test
286
+
287
+ ### Notes
288
+
289
+ - eligible donors from a stock Packet Tracer 9.0.0 install go from **0 to 48**
290
+ under the default policy (270 under `upgradeable`); none of the 292 bundled
291
+ samples carry the previously-required exact build `9.0.0.0810`
292
+ - one test profile, zero skips: **657 passed, 1 skipped**
293
+ - generation works: the corpus generates **32 of 33** scenarios and Packet
294
+ Tracer opens **32 of 32**, with 0 unexpected outcomes
295
+ - `package.json` moves to `0.3.0` for this release
296
+
297
+ ### Generation, measured against live Packet Tracer
298
+
299
+ Everything below was confirmed by opening the file in Packet Tracer, and the
300
+ connectivity claims by running real pings from the devices.
301
+
302
+ - **A rejected donor can no longer rewrite the request.** Donor adaptation
303
+ edited the caller's blueprint, so the first donor tried -- one that could not
304
+ serve a WAN -- turned `R1 Serial0/0/0 <-> R2 Serial0/0/0 (serial)` into
305
+ `GigabitEthernet0/0 <-> GigabitEthernet0/1 (eCrossOver)`, and nothing after it
306
+ could tell serial had been asked for. Each candidate now adapts a copy; only
307
+ the donor committed to writes back.
308
+ - **Interface names come from the device, not from an assumed model.** A switch
309
+ numbering its ports `FastEthernet0/1, 1/1 ... 9/1` was asked for
310
+ `FastEthernet0/2`, and `port_exists` agreed the name was fine because it only
311
+ compared slot depth. The same lab with the uplink on `FastEthernet2/1` opens.
312
+ The same blindness applied to serial: owning two serial ports made
313
+ `Serial0/0/0` acceptable on a router whose interfaces are `Serial2/0` and
314
+ `Serial3/0`.
315
+ - **Serial cables now declare their clocking end.** `DCEDEV`/`DCEPORT` were
316
+ never written, and a lab with any serial cable was refused. Isolated with a
317
+ six-variant experiment: the same topology opens over copper and is refused
318
+ over serial on every valid port pair.
319
+ - **A serial WAN is built end to end from a prompt.** `iki noqte arasinda
320
+ leased line ile 2 router 4 komputer qur` produces two routers over
321
+ `Serial0/1/1 <-> Serial0/1/0`, the file opens, and `PC1 -> 10.1.1.2` crosses
322
+ the WAN 4/4.
323
+ - **DHCP verified live:** four PCs obtained leases from the router pool and ping
324
+ each other and their gateway 4/4.
325
+
326
+ ### Fixed in the tooling that measures all of this
327
+
328
+ - `open_check` gave false verdicts: one lab checked five times answered
329
+ `opened, timeout, timeout, opened, opened`, and a bisect named a culprit that
330
+ a hand-built copy of the same operations opened fine. Each check now opens a
331
+ uniquely named copy, and a negative verdict must reproduce before it is
332
+ reported. Two of the three defects above were invisible until this was fixed.
333
+ - `--doctor` reported `RUNTIME_GRADE ready` with every capability ready and then
334
+ exited 1 with "Runtime is not fully ready", because an optional checksum line
335
+ printed `MISSING`. The verdict now follows the blocking checks.
336
+
337
+ ## [0.2.4] - Unreleased candidate
338
+
339
+ ### Added
340
+
341
+ - Examples Truth 2.0 proof-card and showcase-example surface for the post-`0.2.3` capability release
342
+ - proof-readiness dashboard for ranking the next donor-backed promotion candidates
343
+ - promotion queue artifact for IPv4 routing/management and L2 resiliency/BGP readiness work
344
+ - local sample evidence board that summarizes user-supplied `.pkt/.pka` audit counts without committing raw samples
345
+ - `0.2.4` release notes draft for the next product-hardening patch
346
+
347
+ ### Changed
348
+
349
+ - examples gallery and examples index now distinguish showcase examples, proof cards, local evidence, and promotion candidates
350
+ - current launch wording is being separated from historical `0.2.1`/`0.2.2` runbooks
351
+
352
+ ### Notes
353
+
354
+ - this candidate does not enable broad generation
355
+ - `generate_ready=0` remains intentional
356
+ - `package.json` stays at `0.2.3` until a publish decision is made
357
+
358
+ ## [0.2.3] - 2026-05-03
359
+
360
+ ### Added
361
+
362
+ - voice/collaboration edit-proven proof for IOS `telephony-service`, `ephone-dn`, `ephone`, and `dial-peer voice` command shapes
363
+ - automation/controller edit-proven proof for existing Python, JavaScript, and TCP/UDP script-file replacement
364
+ - L2 security/QoS edit-proven proof for explicit dot1x and QoS IOS switch commands
365
+ - security-edge deepening proof for explicit router CBAC and ZFW IOS commands
366
+ - L2 resiliency + BGP edit-proven proof for explicit BGP, STP/RSTP, EtherChannel/LACP/PAgP, VTP, and DTP IOS commands
367
+ - IPv4 routing/NAT/IOS-management edit-proven proof for explicit OSPFv2, EIGRP IPv4, RIPv2, static/default route, DHCP relay, NAT/PAT, SSH, NTP, and syslog IOS commands
368
+ - local user-supplied Packet Tracer corpus audit via `--local-sample-audit-root` and ignored `output/local-sample-audit.json`
369
+ - donor-backed readiness expansion for dot1x, ZFW, voice/collaboration IOS edits, and automation/controller script-file edits
370
+ - donor-backed readiness expansion for explicit OSPFv3, EIGRP IPv6, RIPng, and IPv6 HSRP edit paths
371
+ - generate-ready pilot design doc that defines the future acceptance gate without enabling broad generate
372
+ - local/cache-only GitHub sample ingestion audit for `.pkt`/`.pka` repositories, license status, decode evidence, and promotion status
373
+
374
+ ### Changed
375
+
376
+ - feature atlas candidate status now promotes `ospfv3`, `eigrp_ipv6`, `ripng`, `hsrp`, `dot1x`, `qos`, `cbac`, and `zfw` only when editor roundtrip and decode-backed evidence exists
377
+ - donor-backed readiness now requires proof-linked sample, decode, parser, and editor roundtrip evidence
378
+ - remote samples with unknown license metadata now stay `reference_only`; permissive-license samples still require decode and inventory validation before curated donor eligibility
379
+ - local `pkt_examples` evidence is now separated from public curated truth; raw `.pkt/.pka` files remain excluded from git and npm
380
+ - README and proof docs now describe `0.2.3` as a capability release, not an unpublished candidate
381
+ - ASA service-policy, clientless VPN, Linksys voice, Network Controller GUI, Blockly, VM/IOx, and broad physical/media workflows remain report-only
382
+
383
+ ### Notes
384
+
385
+ - `0.2.3` is a capability proof/readiness release, not a broad generation release
386
+ - `generate_ready=0` remains intentional until donor-backed acceptance evidence exists
387
+ - broad NAC, QoS, ASA, and security topology generation remains blocked
388
+
389
+ ## [0.2.2]
390
+
391
+ ### Added
392
+
393
+ - advanced wireless proof surface for WEP and WPA Enterprise/RADIUS edit-proven behavior
394
+ - wireless advanced feature atlas coverage for WLC, Meraki, cellular, Bluetooth, beamforming, guest Wi-Fi, WEP, and WPA Enterprise
395
+ - runtime README guidance for generic Twofish bridge paths and search-root fallback
396
+
397
+ ### Changed
398
+
399
+ - package version advanced to `0.2.2` for the README/runtime cleanup and advanced wireless feature wave
400
+ - README runtime setup no longer presents a user-specific local path as the default bridge location
401
+ - advanced wireless prompts now classify into the `wireless_advanced` family without drifting into `service_heavy`
402
+ - WEP and WPA Enterprise/RADIUS are represented as edit-proven where explicit deterministic edit targets exist, while broader WLC/cellular/Bluetooth/Meraki scope remains report-only
403
+
404
+ ### Notes
405
+
406
+ - `0.2.2` remains conservative: no broad synthetic advanced wireless generation is claimed
407
+ - runtime messaging remains Windows-first and explicit about external bridge-assisted validation
408
+
409
+ ## [0.2.1]
410
+
411
+ ### Added
412
+
413
+ - npm tarball hardening for the public package surface
414
+ - launch announcement draft aligned with the current public release wording
415
+
416
+ ### Changed
417
+
418
+ - package version advanced to `0.2.1` because `0.2.0` is already published on npm
419
+ - npm package contents now exclude caches, generated previews, and non-essential screenshot payloads
420
+ - public release references now consistently point to the `0.2.1` patch release artifacts
421
+
422
+ ### Notes
423
+
424
+ - `0.2.1` is the publishable patch release for the conservative public preview surface
425
+ - runtime messaging remains Windows-first and explicit about the external bridge-assisted validation path
426
+
427
+ ## [0.2.0]
46
428
 
47
429
  ### Added
48
430
 
@@ -52,7 +434,7 @@ The format is intentionally simple and release-oriented.
52
434
  - runtime truth, discovery keyword, GitHub metadata, publish-preview roadmap, and curated donor registry docs
53
435
  - seeded curated donor registry entries derived from known working public example artifacts
54
436
  - checked-in Packet Tracer template fallback assets for hermetic builder coverage
55
- - hero demo plan and `0.2.0` release notes draft artifacts for conservative launch prep
437
+ - hero demo plan and `0.2.0` release notes draft artifacts for conservative launch prep
56
438
 
57
439
  ### Changed
58
440