packet-tracer-skill 0.2.3 → 0.3.1
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.
- package/CHANGELOG.md +491 -73
- package/README.md +575 -442
- package/SKILL.md +513 -262
- package/bin/packet-tracer-skill.js +29 -2
- package/docs/github-launch-ops-0.2.3.md +37 -0
- package/docs/github-metadata.md +6 -4
- package/docs/hero-demo-plan.md +1 -1
- package/docs/home-iot-donor-proof.md +4 -4
- package/docs/l2-security-qos-proof.md +1 -1
- package/docs/packet-tracer-feature-gap-atlas.md +4 -4
- package/docs/post-launch-follow-up.md +9 -5
- package/docs/proof-readiness-dashboard.md +69 -0
- package/docs/publish-preview-roadmap.md +6 -5
- package/docs/release-checklist.md +17 -8
- package/docs/release-notes-0.2.4.md +20 -0
- package/docs/runtime-truth.md +33 -8
- package/docs/security-edge-deepening-proof.md +1 -1
- package/examples/README.md +98 -69
- package/examples/complex_campus_master_edit_v4.inventory.json +12 -2
- package/examples/gallery.md +94 -6
- package/examples/home_iot_cli_edit_v1.inventory.json +11 -2
- package/examples/index.json +932 -4
- package/examples/local-sample-evidence.json +24 -0
- package/examples/proof-cards.json +117 -0
- package/examples/service_heavy_cli_edit_v1.inventory.json +11 -2
- package/package.json +61 -53
- package/pytest.ini +9 -0
- package/references/packettracer-sample-catalog.json +45287 -4525
- package/references/packettracer-sample-catalog.md +599 -259
- package/references/proof-readiness-candidates.json +352 -0
- package/scripts/build_examples_index.py +228 -35
- package/scripts/build_sample_catalog.py +62 -40
- package/scripts/corpus_runner.py +430 -0
- package/scripts/coverage_matrix.py +1842 -1812
- package/scripts/donor_cache.py +354 -0
- package/scripts/donor_diagnostics.py +3 -1
- package/scripts/generate_pkt.py +12738 -4228
- package/scripts/intent_parser.py +2269 -1657
- package/scripts/lab_coherence.py +455 -0
- package/scripts/local_donors.py +340 -0
- package/scripts/packet_tracer_env.py +846 -391
- package/scripts/pkt_annotate.py +218 -0
- package/scripts/pkt_codec.py +420 -181
- package/scripts/pkt_editor.py +2487 -1703
- package/scripts/pkt_transformer.py +1170 -727
- package/scripts/pkt_verify.py +461 -0
- package/scripts/runtime_doctor.py +80 -29
- package/scripts/sample_catalog.py +1425 -1250
- package/scripts/twofish_diagnostics.py +48 -31
- package/scripts/usage_ledger.py +218 -0
- package/scripts/vendor/README.md +44 -37
- package/scripts/vendor/twofish_pure.py +321 -0
- package/scripts/workspace_repair.py +548 -508
- package/templates/pt900/donors/README.md +15 -0
package/SKILL.md
CHANGED
|
@@ -1,262 +1,513 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pkt
|
|
3
|
-
description: >
|
|
4
|
-
Create and edit Cisco Packet Tracer 9.0 `.pkt` files from hybrid natural-language
|
|
5
|
-
requests and explicit commands. Use this skill for topology generation, VLAN/router-on-a-stick,
|
|
6
|
-
DHCP, management VLAN, Telnet, wireless/AP-client setup, server services, and existing `.pkt` edits.
|
|
7
|
-
---
|
|
8
|
-
|
|
9
|
-
# Cisco Packet Tracer 9.0 `.pkt` Hybrid Generator/Editor
|
|
10
|
-
|
|
11
|
-
This skill targets Packet Tracer
|
|
12
|
-
binary blob, not a zip
|
|
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
|
-
the
|
|
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
|
-
|
|
1
|
+
---
|
|
2
|
+
name: pkt
|
|
3
|
+
description: >
|
|
4
|
+
Create and edit Cisco Packet Tracer 9.0 `.pkt` files from hybrid natural-language
|
|
5
|
+
requests and explicit commands. Use this skill for topology generation, VLAN/router-on-a-stick,
|
|
6
|
+
DHCP, management VLAN, Telnet, wireless/AP-client setup, server services, and existing `.pkt` edits.
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
# Cisco Packet Tracer 9.0 `.pkt` Hybrid Generator/Editor
|
|
10
|
+
|
|
11
|
+
This skill targets whichever Packet Tracer release is installed (detected at runtime,
|
|
12
|
+
9.0 by default) and treats a `.pkt` file as a single binary blob, not a zip
|
|
13
|
+
container or folder tree.
|
|
14
|
+
|
|
15
|
+
The current builder/editor is Cisco-sample-centric:
|
|
16
|
+
|
|
17
|
+
- installed Packet Tracer sample saves are the primary prototype source
|
|
18
|
+
- bundled device templates are the secondary fallback for gaps such as missing
|
|
19
|
+
device families in Cisco's own saves
|
|
20
|
+
- imported external labs are reference-only by default
|
|
21
|
+
- curated external donor roots can become donor-eligible after validation, but
|
|
22
|
+
Cisco local donors still rank first
|
|
23
|
+
|
|
24
|
+
That is intentional: it avoids the invalid synthetic XML approach that Packet
|
|
25
|
+
Tracer rejects while still keeping the skill usable when Cisco's own sample set
|
|
26
|
+
does not cover a device family directly.
|
|
27
|
+
|
|
28
|
+
The prompt-first architecture now follows a planner/validator/autofix split:
|
|
29
|
+
|
|
30
|
+
1. intent extraction
|
|
31
|
+
2. topology/config planning
|
|
32
|
+
3. donor ranking
|
|
33
|
+
4. donor-prune mutation
|
|
34
|
+
5. compatibility validation
|
|
35
|
+
|
|
36
|
+
Useful ideas from `MCP-Packet-Tracer` were adopted only at the architecture
|
|
37
|
+
level. PTBuilder live deploy and external donor usage were intentionally not
|
|
38
|
+
adopted.
|
|
39
|
+
|
|
40
|
+
## Using This Skill Correctly
|
|
41
|
+
|
|
42
|
+
Read this before generating anything. Every rule below was learned by measuring
|
|
43
|
+
a lab that looked finished and was not.
|
|
44
|
+
|
|
45
|
+
### A lab that opens is not a lab that works
|
|
46
|
+
|
|
47
|
+
This is the single most expensive mistake available here. Generated labs have
|
|
48
|
+
passed every structural check, opened cleanly in Packet Tracer, read correctly
|
|
49
|
+
line by line, and been unable to pass a single packet. "It opened" tells you
|
|
50
|
+
the container is valid. It tells you nothing about the network.
|
|
51
|
+
|
|
52
|
+
Two things separate a finished lab from a plausible one:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
python scripts/generate_pkt.py --coherence-report output/lab.pkt
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
and a live ping. Do both. `--coherence-report` exits non-zero when the lab
|
|
59
|
+
contradicts itself, and generation prints the same summary as a `WARNING:` line
|
|
60
|
+
when it hands the file over — never ignore that line.
|
|
61
|
+
|
|
62
|
+
### What the coherence report is telling you
|
|
63
|
+
|
|
64
|
+
Every defect this project has paid for has one shape: **a fact derived twice,
|
|
65
|
+
in two passes, with nothing comparing the derivations.** Each half reads
|
|
66
|
+
correctly on its own. The report is that comparison:
|
|
67
|
+
|
|
68
|
+
| Finding | What it means |
|
|
69
|
+
|---|---|
|
|
70
|
+
| `interface_declared_twice` | IOS keeps the last block; readers scan the first |
|
|
71
|
+
| `port_not_on_device` | Packet Tracer refuses to open the file |
|
|
72
|
+
| `port_double_booked` | two cables on one socket |
|
|
73
|
+
| `duplicate_address` | two interfaces claim one address |
|
|
74
|
+
| `real_address_is_also_virtual` | a router holds an address that is someone's HSRP virtual |
|
|
75
|
+
| `native_vlan_mismatch` | spanning tree blocks a cabled, configured port |
|
|
76
|
+
| `etherchannel_peer_does_not_bundle` | the switch behind it drops off the network |
|
|
77
|
+
| `gateway_answers_for_nobody` | a static host points at an address nothing holds |
|
|
78
|
+
| `pool_without_interface` | DHCP hands out addresses nothing can route |
|
|
79
|
+
|
|
80
|
+
The report never repairs. A checker that fixes what it finds stops being able
|
|
81
|
+
to tell you whether the thing it checks is working.
|
|
82
|
+
|
|
83
|
+
### Measuring in a live Packet Tracer
|
|
84
|
+
|
|
85
|
+
Three steps, in order, every time:
|
|
86
|
+
|
|
87
|
+
1. **Confirm which document is open.** With two windows open the bridge answers
|
|
88
|
+
for the other one. A pass rate measured against the wrong lab is worse than
|
|
89
|
+
no measurement, because it is believed. Check the device list first.
|
|
90
|
+
2. **Throw the first reading away.** Spanning tree has not converged; the first
|
|
91
|
+
ping after opening a large lab reports 0/4 on a path that works. It is not a
|
|
92
|
+
measurement, it is the lab starting up.
|
|
93
|
+
3. **Then measure.** A *failing* ping takes far longer than a passing one --
|
|
94
|
+
each packet waits out its own timeout, about 13 seconds for four -- so
|
|
95
|
+
budget 45-60s per call rather than reading a timeout as a failure.
|
|
96
|
+
|
|
97
|
+
Ping from a host. Routers and switches answer through a different bridge path
|
|
98
|
+
that is not reliable here.
|
|
99
|
+
|
|
100
|
+
### When two repairs in a row do not change the measurement
|
|
101
|
+
|
|
102
|
+
Stop repairing. The symptom is not where the defect is. Find the pass that
|
|
103
|
+
wrote the state, and fix it there. The fastest way in: **diff the broken device
|
|
104
|
+
against a working sibling.** One switch unreachable while identical ones work
|
|
105
|
+
has one extra line, and reading configuration top to bottom will not find it as
|
|
106
|
+
quickly as `diff` will.
|
|
107
|
+
|
|
108
|
+
### Facts about Packet Tracer that cost a lab each
|
|
109
|
+
|
|
110
|
+
- a copper cable in a fibre socket is **dropped in silence** -- the file opens,
|
|
111
|
+
the cable is simply not there
|
|
112
|
+
- a duplicate `interface` block is applied last-wins, while readers scan the first
|
|
113
|
+
- a subinterface `ip address` before its `encapsulation dot1Q` is refused
|
|
114
|
+
silently
|
|
115
|
+
- `PORT_DHCP_ENABLE=true` makes Packet Tracer ignore the static address in the
|
|
116
|
+
file; a host with both is a DHCP client, and judging it on its stale address
|
|
117
|
+
is a false reading
|
|
118
|
+
- DHCP snooping with no trusted uplink eats every offer the router sends
|
|
119
|
+
- port security on a trunk isolates the whole switch behind it
|
|
120
|
+
- a `channel-group` whose peer does not bundle takes that switch off the network
|
|
121
|
+
- an interface name the device does not own blocks the file from opening at all;
|
|
122
|
+
a double-booked port does not
|
|
123
|
+
- a `vlan N` line in a switch's configuration does **not** create the VLAN --
|
|
124
|
+
Packet Tracer keeps the database separately, and a port assigned to a VLAN
|
|
125
|
+
that is not in it forwards nothing
|
|
126
|
+
- a top-level command written straight after an indented sub-block line is
|
|
127
|
+
swallowed; the `!` between them is load-bearing
|
|
128
|
+
- a home router's sockets are named, not slotted, and the spelling is the
|
|
129
|
+
model's: `Ethernet 1` .. `4` on `WirelessRouter`, `GigabitEthernet 1` .. `4`
|
|
130
|
+
on `WirelessRouterNewGeneration`, and `Internet` for the uplink on both. It
|
|
131
|
+
writes no interfaces into its configuration, so nothing else can tell you
|
|
132
|
+
- a home router's LAN address is a **setting**, not a config line, and lives in
|
|
133
|
+
`ENGINE/LAN_IP_ADDRESS` with its pool under `ENGINE/DHCP_SERVER/POOLS/POOL`;
|
|
134
|
+
a reader that only walks running configs cannot see it
|
|
135
|
+
- a wireless client's addressing comes from its `WIRELESS_PROFILE`, not from
|
|
136
|
+
its port -- both record it, and Packet Tracer obeys the profile
|
|
137
|
+
- a radio link is made by **distance**. A client outside the access point's
|
|
138
|
+
`COVERAGERANGE` reports its port `up` and `linked` and passes nothing
|
|
139
|
+
- an access point's WPA key lives in `WIRELESS_COMMON/WEP_PROCESS/KEY` with
|
|
140
|
+
`WEP_PROCESS/ENCRYPTION`, never in `WPA_PASSPHRASE`. The names are legacy and
|
|
141
|
+
WPA2 uses them; the client side is the same shape. Put it in the wrong field
|
|
142
|
+
and the access point runs WPA2 with no key while its clients have one
|
|
143
|
+
- a wireless client reads `ip 0.0.0.0` at its un-negotiated rate for the first
|
|
144
|
+
moments after a lab opens, even in a lab Packet Tracer saved itself while it
|
|
145
|
+
was pinging 4/4. `pt_inspect_ports` right after opening is a **first reading**
|
|
146
|
+
and has to be discarded exactly like a first ping
|
|
147
|
+
- a home router's DHCP **lease records** are how a client gets its address back
|
|
148
|
+
when the file opens; move its LAN and they have to be renumbered, not dropped
|
|
149
|
+
- the builder MCP's device table is not authoritative about port names; it
|
|
150
|
+
gives the AC home router `Ethernet 1` .. `4`, and the device itself says
|
|
151
|
+
`GigabitEthernet 1` .. `4`. `pt_inspect_ports` answers at the IOS layer,
|
|
152
|
+
where those sockets are bridged into `Vlan1` and do not appear at all --
|
|
153
|
+
`pt_query_topology` is the one that lists them
|
|
154
|
+
|
|
155
|
+
### Drawing the topology yourself
|
|
156
|
+
|
|
157
|
+
The generator packs switch blocks into a roughly square grid, which is fine for
|
|
158
|
+
a lab nobody planned. When you have already decided the shape -- which
|
|
159
|
+
department sits where, which switch faces which, where the core belongs -- say
|
|
160
|
+
so in the blueprint and set `PACKET_TRACER_LAYOUT=keep`. Every `x`/`y` in the
|
|
161
|
+
blueprint is then left exactly as given, and the frames are drawn around the
|
|
162
|
+
devices where they land.
|
|
163
|
+
|
|
164
|
+
Sketch first, build second, is the better order for anything a person will
|
|
165
|
+
look at: you can see the whole diagram before a single cable exists, and the
|
|
166
|
+
skill's job narrows to making the file match the drawing.
|
|
167
|
+
|
|
168
|
+
Without the knob the packing applies, and it is deterministic: the same
|
|
169
|
+
blueprint gives the same coordinates every time, so a regenerated lab does not
|
|
170
|
+
drift.
|
|
171
|
+
|
|
172
|
+
### Scale
|
|
173
|
+
|
|
174
|
+
There is no artificial device limit. The only ceiling is physical: a switch has
|
|
175
|
+
the ports it has, and the generator says so plainly when it runs out. Ask for
|
|
176
|
+
more switches, not fewer hosts.
|
|
177
|
+
|
|
178
|
+
### A generated lab becomes the next build's donor
|
|
179
|
+
|
|
180
|
+
Donor selection can pick a lab this skill produced, so every repair pass
|
|
181
|
+
eventually runs over its own output. Write interface configuration with
|
|
182
|
+
`_set_config_block`, never by appending, and check a new pass by running it
|
|
183
|
+
three times and asserting the document stops changing after the first.
|
|
184
|
+
|
|
185
|
+
### The palette is not the vocabulary
|
|
186
|
+
|
|
187
|
+
Packet Tracer's device palette lists more kinds than a saved lab distinguishes:
|
|
188
|
+
`SMARTPHONE-PT` saves as `Pda`, `Fiber Patch Panel` saves as `Patch Panel`.
|
|
189
|
+
Adding an askable kind with no donor behind it produces a request that can only
|
|
190
|
+
come back as an undelivered device. `tests/test_askable_kinds_have_donors.py`
|
|
191
|
+
holds the vocabulary to what real labs actually contain, in both directions.
|
|
192
|
+
|
|
193
|
+
### When generation refuses
|
|
194
|
+
|
|
195
|
+
A refusal returns `blocking_gaps` together with a `blueprint_plan`. That is not
|
|
196
|
+
a failure to work around by loosening a policy -- it is the skill saying no
|
|
197
|
+
donor can serve the request. Read the gaps, adjust the request or supply a
|
|
198
|
+
donor, and try again.
|
|
199
|
+
|
|
200
|
+
### What works without Packet Tracer installed
|
|
201
|
+
|
|
202
|
+
Decode, inventory, edit, generate and structural verification all work from the
|
|
203
|
+
donor cache with no install and no environment variables -- the Twofish engine
|
|
204
|
+
is vendored pure Python. Only `--validate-open` and live pings need the
|
|
205
|
+
application itself. Tests that build a lab are marked `requires_donors` and skip
|
|
206
|
+
where there is nothing to build from.
|
|
207
|
+
|
|
208
|
+
## How `.pkt` Files Work
|
|
209
|
+
|
|
210
|
+
For the modern format targeted by this skill, the pipeline is:
|
|
211
|
+
|
|
212
|
+
1. Build a Packet Tracer XML document rooted at `<PACKETTRACER5>`
|
|
213
|
+
2. qCompress the UTF-8 XML bytes using:
|
|
214
|
+
- 4-byte big-endian uncompressed length
|
|
215
|
+
- raw zlib payload
|
|
216
|
+
3. Apply Stage-2 XOR obfuscation
|
|
217
|
+
4. Encrypt with Twofish in EAX mode and append the 16-byte authentication tag
|
|
218
|
+
5. Apply Stage-1 reverse/XOR obfuscation
|
|
219
|
+
|
|
220
|
+
The XML includes a `<VERSION>` value such as `9.0.0.0810`. This skill targets the
|
|
221
|
+
9.0 line.
|
|
222
|
+
|
|
223
|
+
Packet Tracer 5.x and 6.x wrote a simpler container: qCompress output XORed
|
|
224
|
+
byte-wise with `(length - index)`, with no cipher and no tag. 18 of the 292
|
|
225
|
+
bundled samples are still in that format. `decode_pkt_auto` reads both and
|
|
226
|
+
reports which one matched.
|
|
227
|
+
|
|
228
|
+
Packet Tracer also writes raw control bytes into element text — a Cisco banner
|
|
229
|
+
delimiter is literally `banner motd `, which XML 1.0 forbids. Use
|
|
230
|
+
`parse_pkt_xml` / `serialize_pkt_xml` rather than `ET.fromstring` / `ET.tostring`
|
|
231
|
+
so those bytes survive a round trip.
|
|
232
|
+
|
|
233
|
+
The Twofish step needs no compiled binary. `scripts/vendor/twofish_pure.py` is a
|
|
234
|
+
vendored pure-Python implementation verified against the official Twofish test
|
|
235
|
+
vectors, so decode/edit/generate work on a clean checkout with no environment
|
|
236
|
+
variables. A compiled `_twofish` bridge is optional: when `PKT_TWOFISH_LIBRARY`
|
|
237
|
+
or `PKT_TWOFISH_SEARCH_ROOTS` resolves one, it is used automatically as a ~12x
|
|
238
|
+
accelerator for large labs.
|
|
239
|
+
|
|
240
|
+
### Donor Version Compatibility
|
|
241
|
+
|
|
242
|
+
The build field in a `<VERSION>` string is not a schema identifier — it changes
|
|
243
|
+
on every point release and re-save. None of the 292 sample saves bundled with
|
|
244
|
+
Packet Tracer 9.0.0 carry `9.0.0.0810`; 48 are `9.0.0.x` with other builds and
|
|
245
|
+
the rest span 5.x through 8.x. Donors are therefore classified into tiers:
|
|
246
|
+
|
|
247
|
+
| Tier | Meaning |
|
|
248
|
+
|---|---|
|
|
249
|
+
| `exact` | build strings identical |
|
|
250
|
+
| `same_minor` | same `major.minor`, e.g. any `9.0.0.x` |
|
|
251
|
+
| `same_major` | same major, different minor |
|
|
252
|
+
| `upgradeable` | 6.x–8.x; Packet Tracer upgrades these on open |
|
|
253
|
+
| `incompatible` | 5.x and older |
|
|
254
|
+
|
|
255
|
+
`PACKET_TRACER_DONOR_POLICY` names the loosest acceptable tier. The default is
|
|
256
|
+
`same_minor`. When several donors qualify, the strictest tier wins.
|
|
257
|
+
|
|
258
|
+
The target version is **detected**, not hardcoded. Resolution order:
|
|
259
|
+
`PACKET_TRACER_TARGET_VERSION` → the installed Packet Tracer's directory name →
|
|
260
|
+
the compatibility donor's own `<VERSION>` → the built-in default. Installing
|
|
261
|
+
Packet Tracer 8.2 makes the skill target 8.2 and accept 8.2.x donors; no
|
|
262
|
+
configuration is needed to follow a different release.
|
|
263
|
+
|
|
264
|
+
## Workflow
|
|
265
|
+
|
|
266
|
+
1. Parse the request into a hybrid intent plan:
|
|
267
|
+
- topology, device models, links, cable types, ports
|
|
268
|
+
- natural Azerbaijani or mixed-language counts such as `3 dene switch ve 6 komputer`
|
|
269
|
+
- department/campus prompts such as `6 sobeli kampus sebekesi`
|
|
270
|
+
- VLAN/trunk/access/router-on-a-stick intent
|
|
271
|
+
- router DHCP or server DHCP/DNS intent
|
|
272
|
+
- management VLAN / Telnet intent
|
|
273
|
+
- AP SSID/security and wireless client association intent
|
|
274
|
+
- existing `.pkt` edit operations when a source file is provided
|
|
275
|
+
2. Build an intent-first topology/config plan:
|
|
276
|
+
- topology archetype
|
|
277
|
+
- device list
|
|
278
|
+
- port map
|
|
279
|
+
- VLAN/service/config plan
|
|
280
|
+
- assumptions and blocking gaps
|
|
281
|
+
3. Rank Cisco local donor candidates with capability, topology, and donor-graph scoring
|
|
282
|
+
4. Optionally search/import remote labs, then rank imported labs as curated donors or reference patterns
|
|
283
|
+
5. Apply donor-prune mutations on one working Cisco 9.0 donor lab
|
|
284
|
+
6. Validate workspace/runtime/scenario compatibility
|
|
285
|
+
7. Encode XML into a `.pkt` blob with `scripts/pkt_codec.py`
|
|
286
|
+
8. Save generated or edited output locally
|
|
287
|
+
|
|
288
|
+
Open-first rules remain strict:
|
|
289
|
+
|
|
290
|
+
- multi-source search and scoring is allowed
|
|
291
|
+
- final `.pkt` apply is still single-donor
|
|
292
|
+
- when no safe donor exists, return `blocking_gaps` plus a `blueprint_plan`
|
|
293
|
+
|
|
294
|
+
## Files
|
|
295
|
+
|
|
296
|
+
- `scripts/pkt_builder.py`
|
|
297
|
+
Thin entrypoint: selects a sample and delegates to `pkt_transformer`
|
|
298
|
+
- `scripts/pkt_codec.py`
|
|
299
|
+
Encodes and decodes the modern `.pkt` format
|
|
300
|
+
- `scripts/vendor/twofish_pure.py`
|
|
301
|
+
Vendored pure-Python Twofish; the repo-local baseline engine
|
|
302
|
+
- `scripts/pkt_verify.py`
|
|
303
|
+
Two-tier verification: headless structural checks, plus a real Packet Tracer
|
|
304
|
+
open test that watches for the file's window
|
|
305
|
+
- `scripts/usage_ledger.py`
|
|
306
|
+
Local, gitignored record of which donors actually worked, fed back into donor
|
|
307
|
+
ranking so the skill improves with use
|
|
308
|
+
- `scripts/generate_pkt.py`
|
|
309
|
+
CLI entrypoint for generate/edit/decode/inventory/explain-plan
|
|
310
|
+
- `scripts/intent_parser.py`
|
|
311
|
+
Hybrid natural-language and mini-DSL parser
|
|
312
|
+
- `scripts/pkt_editor.py`
|
|
313
|
+
Existing `.pkt` inventory and mutation engine
|
|
314
|
+
- `scripts/sample_catalog.py`
|
|
315
|
+
Capability-tagged sample index and reference-pattern loader
|
|
316
|
+
- `scripts/sample_selector.py`
|
|
317
|
+
Sample ranking by capability, topology, trust level, and prototype eligibility
|
|
318
|
+
- `scripts/packet_tracer_env.py`
|
|
319
|
+
Resolves Packet Tracer install, saves root, and executable paths
|
|
320
|
+
- `scripts/runtime_doctor.py`
|
|
321
|
+
Unified runtime diagnostics for host OS, donor, Packet Tracer paths, and Twofish readiness
|
|
322
|
+
- `templates/pt900/base_empty.xml`
|
|
323
|
+
Base Packet Tracer 9.0 skeleton
|
|
324
|
+
- `templates/pt900/device_library/*.xml`
|
|
325
|
+
Secondary fallback device XML templates for the first supported device set
|
|
326
|
+
|
|
327
|
+
The runtime builder currently prefers the installed FTP sample from the local
|
|
328
|
+
Packet Tracer `saves/` directory. The exact path is resolved at runtime from
|
|
329
|
+
the local Packet Tracer installation or the `PACKET_TRACER_*` environment
|
|
330
|
+
variables.
|
|
331
|
+
|
|
332
|
+
Prompt-driven donor-prune generation prefers an explicit
|
|
333
|
+
`PACKET_TRACER_COMPAT_DONOR`, but it can also auto-detect a working local
|
|
334
|
+
Packet Tracer 9.0 donor from common local locations when the environment
|
|
335
|
+
override is absent.
|
|
336
|
+
|
|
337
|
+
Strict compatibility rules:
|
|
338
|
+
|
|
339
|
+
- the target version is detected from the install; override with `PACKET_TRACER_TARGET_VERSION` only when you need to pin it
|
|
340
|
+
- never accept a `5.x` donor; Packet Tracer does not reliably upgrade those
|
|
341
|
+
- the donor tier that was accepted is recorded in `compatibility_tier` and
|
|
342
|
+
reported as an assumption, never hidden
|
|
343
|
+
- if the donor is missing, undecodable, or below the active policy tier, stop
|
|
344
|
+
with a blocking error that names the tier and the policy needed to accept it
|
|
345
|
+
- if `PACKET_TRACER_COMPAT_DONOR` is explicitly set and rejected, do not silently
|
|
346
|
+
fall back to another donor
|
|
347
|
+
- `PACKET_TRACER_*` variables must be inherited by every host process;
|
|
348
|
+
`PKT_TWOFISH_*` is optional and only selects the compiled accelerator
|
|
349
|
+
|
|
350
|
+
## Supported First Iteration
|
|
351
|
+
|
|
352
|
+
- `Router`, `Switch`, `PC`, `Server`
|
|
353
|
+
- `LightWeightAccessPoint` / `WirelessRouter` where sample prototypes exist
|
|
354
|
+
- natural prompt planning for device counts, VLAN IDs, `gig` uplinks, `fa` host links,
|
|
355
|
+
department/campus prompts, and default `chain` / `core switch` topologies
|
|
356
|
+
- structured `blocking_gaps`, `assumptions_used`, and `confidence_score` reporting
|
|
357
|
+
- transparent `explain-plan` output with:
|
|
358
|
+
- `intent_plan`
|
|
359
|
+
- `topology_plan`
|
|
360
|
+
- `config_plan`
|
|
361
|
+
- `estimate_plan`
|
|
362
|
+
- `preflight_validation`
|
|
363
|
+
- `autofix_summary`
|
|
364
|
+
- `cisco_sample_candidates`
|
|
365
|
+
- `curated_external_donor_candidates`
|
|
366
|
+
- `external_reference_patterns`
|
|
367
|
+
- `validation_report`
|
|
368
|
+
- explicit port-to-port and cable/media mapping
|
|
369
|
+
- VLAN create, access port, trunk port, native VLAN
|
|
370
|
+
- router subinterfaces and router-on-a-stick
|
|
371
|
+
- named ACL create, permit/deny rule injection, and `ip access-group` interface binding
|
|
372
|
+
- router DHCP pool
|
|
373
|
+
- server DHCP pool, DNS enablement, and DNS records
|
|
374
|
+
- HTTP / HTTPS / FTP / TFTP / NTP service enable state
|
|
375
|
+
- end-device DNS client settings
|
|
376
|
+
- management VLAN SVI + default gateway
|
|
377
|
+
- Telnet enablement on switches/routers via config mutations
|
|
378
|
+
- wireless SSID/security/channel mutations
|
|
379
|
+
- wireless client association and DHCP/static mode where compatible prototypes exist
|
|
380
|
+
- existing `.pkt` inventory and edit flow
|
|
381
|
+
|
|
382
|
+
## Defaults
|
|
383
|
+
|
|
384
|
+
If the user does not specify details:
|
|
385
|
+
|
|
386
|
+
- Packet Tracer version: `9.0.0.0810`
|
|
387
|
+
- Subnet: `192.168.1.0/24`
|
|
388
|
+
- Default gateway: `192.168.1.1`
|
|
389
|
+
- PC addresses: `.10`, `.11`, `.12`, ...
|
|
390
|
+
- Layout:
|
|
391
|
+
- router around `(400, 140)`
|
|
392
|
+
- switch around `(400, 280)`
|
|
393
|
+
- PCs along the bottom row
|
|
394
|
+
|
|
395
|
+
## Constraints
|
|
396
|
+
|
|
397
|
+
- The builder needs Packet Tracer's bundled sample saves as prototype sources,
|
|
398
|
+
from a local installation on Windows, macOS or Linux **or** from the donor
|
|
399
|
+
cache under `~/.pkt/saves`, which a single generate run on an installed
|
|
400
|
+
machine populates and which can then be copied anywhere
|
|
401
|
+
- Donor devices the plan does not need are deleted. `PACKET_TRACER_SPARE_STRATEGY=park`
|
|
402
|
+
restores the older behaviour of renaming them `UNUSED-*` / `*-SPARE-*` and
|
|
403
|
+
moving them offscreen, if a donor turns out to depend on one staying present
|
|
404
|
+
- `--validate-open` needs Packet Tracer installed. Everything else — decode,
|
|
405
|
+
inventory, edit, generate, structural verification — does not
|
|
406
|
+
- The bundled template library is intentionally minimal in v1
|
|
407
|
+
- Imported external sample roots are reference-only unless you explicitly promote them
|
|
408
|
+
- Prompt generation in the default path is donor-prune based, not full synthetic rebuild
|
|
409
|
+
- Host-to-VLAN distribution is defaulted to an even split when not given, and the
|
|
410
|
+
split is reported as an assumption. `PACKET_TRACER_STRICT_VLAN_ASSIGNMENT=1`
|
|
411
|
+
refuses instead
|
|
412
|
+
- Links the donor lacks are built rather than refused. `PACKET_TRACER_LINK_STRATEGY=reuse`
|
|
413
|
+
restricts generation to the donor's own topology
|
|
414
|
+
- Manual validation in Packet Tracer is still required before claiming a topology
|
|
415
|
+
is fully compatible with the Cisco application
|
|
416
|
+
|
|
417
|
+
## CLI Examples
|
|
418
|
+
|
|
419
|
+
Generate from a blueprint file:
|
|
420
|
+
|
|
421
|
+
```powershell
|
|
422
|
+
python scripts/generate_pkt.py --blueprint examples/blueprint_minimal.json --output output\minimal.pkt
|
|
423
|
+
```
|
|
424
|
+
|
|
425
|
+
Check what a finished lab contradicts about itself, and exit non-zero if it does:
|
|
426
|
+
|
|
427
|
+
```powershell
|
|
428
|
+
python scripts/generate_pkt.py --coherence-report output\campus.pkt
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
Generate from a hybrid prompt:
|
|
432
|
+
|
|
433
|
+
```powershell
|
|
434
|
+
python scripts/generate_pkt.py --prompt "6 şöbəli şəbəkə qur, VLAN 10 20 30 40 50 60 və management VLAN 99 yarat" --output output\campus.pkt
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
Explain the parsed plan before generation:
|
|
438
|
+
|
|
439
|
+
```powershell
|
|
440
|
+
python scripts/generate_pkt.py --explain-plan "set SW1 vlan 10 name Finance; enable telnet on SW1 username admin password 1234"
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
Explain a natural Azerbaijani prompt before generation:
|
|
444
|
+
|
|
445
|
+
```powershell
|
|
446
|
+
python scripts/generate_pkt.py --explain-plan "3 dene switch ve 6 komputer ve 1 router vlanlarda 10,20,30 switchlerin oz aralarinda ve routerle aralarinda gig portuna qosulsun komputerler ise fa portlarla qosulsun"
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
Inspect curated donor candidates from a local imported lab root:
|
|
450
|
+
|
|
451
|
+
```powershell
|
|
452
|
+
python scripts/generate_pkt.py --explain-plan "6 şöbəli şəbəkə qur, hər şöbədə 1 switch 1 AP 1 printer 2 PC 2 tablet olsun" --donor-root C:\labs\curated-pkt-donors --reference-root C:\labs\external-pkt-samples
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
Only external `9.0.0.0810` labs are promoted into the curated donor pool when
|
|
456
|
+
their workspace validation passes cleanly, or when they are `legacy_uuid_physical`
|
|
457
|
+
donors whose only logical warnings are repeated `MEM_ADDR` mismatch records.
|
|
458
|
+
|
|
459
|
+
Search GitHub first, then auto-import matching repos into a local cache:
|
|
460
|
+
|
|
461
|
+
```powershell
|
|
462
|
+
python scripts/generate_pkt.py --explain-plan "6 department campus with vlan dhcp dns ap" --search-remote --remote-provider github --import-cache-root output\remote-cache
|
|
463
|
+
```
|
|
464
|
+
|
|
465
|
+
Print the aggregated capability matrix:
|
|
466
|
+
|
|
467
|
+
```powershell
|
|
468
|
+
python scripts/generate_pkt.py --coverage-report
|
|
469
|
+
python scripts/generate_pkt.py --coverage-report --device-family "access points"
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
Inspect an existing `.pkt` inventory:
|
|
473
|
+
|
|
474
|
+
```powershell
|
|
475
|
+
python scripts/generate_pkt.py --inventory input\lab.pkt
|
|
476
|
+
python scripts/generate_pkt.py --inventory input\lab.pkt --inventory-capabilities
|
|
477
|
+
```
|
|
478
|
+
|
|
479
|
+
Edit an existing `.pkt` directly from a prompt:
|
|
480
|
+
|
|
481
|
+
```powershell
|
|
482
|
+
python scripts/generate_pkt.py --edit input\lab.pkt --prompt "set Wireless Router0 ssid FIN_WIFI security wpa2-psk passphrase fin12345 channel 6 associate PC0 to Wireless Router0 ssid FIN_WIFI dhcp" --output output\edited_lab.pkt --xml-out output\edited_lab.xml
|
|
483
|
+
python scripts/generate_pkt.py --edit input\lab.pkt --prompt "enable dns on Server0 set Server0 dns A www.example.local 192.168.10.20 set PC0 dns 192.168.10.20" --output output\edited_services.pkt
|
|
484
|
+
```
|
|
485
|
+
|
|
486
|
+
Decode a `.pkt` back to XML for inspection:
|
|
487
|
+
|
|
488
|
+
```powershell
|
|
489
|
+
python scripts/generate_pkt.py --decode output\minimal.pkt --xml-out output\minimal.xml
|
|
490
|
+
```
|
|
491
|
+
|
|
492
|
+
Verify a generated file. The structural tier is headless; `--open` launches
|
|
493
|
+
Packet Tracer and waits until the file's own window appears:
|
|
494
|
+
|
|
495
|
+
```powershell
|
|
496
|
+
python scripts/pkt_verify.py output\minimal.pkt
|
|
497
|
+
python scripts/pkt_verify.py output\minimal.pkt --open
|
|
498
|
+
python scripts/generate_pkt.py --validate-open output\minimal.pkt
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
A file that fails the structural tier is never handed to Packet Tracer.
|
|
502
|
+
|
|
503
|
+
Inspect what the skill has learned from previous runs:
|
|
504
|
+
|
|
505
|
+
```powershell
|
|
506
|
+
python scripts/usage_ledger.py
|
|
507
|
+
```
|
|
508
|
+
|
|
509
|
+
Learning is local and on by default. Prompts are stored only as a non-reversible
|
|
510
|
+
fingerprint, the ledger lives under gitignored `output/`, and it is never
|
|
511
|
+
committed or packaged. Set `PKT_USAGE_LEDGER=off` to disable it, or point it at
|
|
512
|
+
another path. Deleting the ledger changes results in no way except donor
|
|
513
|
+
ordering.
|