Stopped on request, out of budget. Nothing is half-committed: three specs closed cleanly with two commits each, and the fourth is coherent uncommitted work whose last agent was killed mid-phase.
The previous handover, the spec-closing sweep of 2026-09-07/08, is spent and has
been removed. Two of its open items resolved themselves: spec-verification-debt-clearing
is closed, and test/rfc-changed/1bfe298a.md no longer exists. One survives and is
carried in section 5.
Thomas asked what in a VyOS security advisory (twelve accel-ppp defects) applied to Ze. Six audits established that eight of the twelve cannot reproduce here: four are protocols Ze does not speak (SSTP, PPTP, IPoE, NHRP), and stack buffer overflow plus uninitialized-memory disclosure are C failure modes Go removes. The RADIUS authentication bypass, the one item that transfers as pure logic, is already closed in Ze: a reply is matched on server plus Identifier and verified against the Response Authenticator before the pending request resolves.
Four real defects came out of the audits, each became a spec, and three are now in HEAD.
| Spec | Commits | What it fixed |
|---|---|---|
pppoe-discovery-omits-the-mandatory-service-name-tag |
0e1543cc9a, e03d31b81e |
PADO and PADS always carry exactly one Service-Name tag; a tagless PADR is refused. Closed RFC2516-5.2-2, the one published MUST gap for PPPoE |
pppoe-padr-replay-allocates-unbounded-sessions |
4efaa4fd8d, 75e3a2ef43 |
A replayed PADR no longer allocates without bound. Per-MAC cap, multi-session MAC index, cookie-keyed dedup, and a Session.State data race closed |
ipv6cp-accepts-and-proposes-a-zero-interface-identifier |
fd7cd7b44e, 3fd87369fb |
All four RFC 5072 Section 4.1 outcomes, the pppd one-shot Nak guard, and a suggestion generator that clears the "u" bit |
Each Review Gate found a defect all its implementation phases had missed. That is the pattern worth budgeting for: the gate is defect-finding, not paperwork.
spec-subscriber-reader-loops-retry-a-failing-socket-without-backoff is closed.
Everything below this heading is the record of how it got there, kept because the
Phase 6 finding outlives the spec. What replaced its one outstanding item was
spec-failing-socket-proof-needs-a-non-ptrace-injection-point, closed on
2026-09-11: ./le test fail-syscall (internal/test/failsyscall) fails one named
syscall through a classic seccomp filter and then execs the daemon, so nothing
traces it and the failing call is charged to the daemon's own CPU.
internal/core/pacer holds Pacer, a value type whose zero value is ready to use.
Wait(stop <-chan struct{}) bool returns true when the caller must exit, reuses one
timer so it allocates nothing after the first wait, and selects on the caller's own
exit signal. Succeed() resets. Growth doubles from a 10ms step to a 250ms ceiling.
All four receiver loops pace, log and count:
| Loop | File | Exit signal |
|---|---|---|
(*UDPListener).readLoop |
internal/component/l2tp/listener.go |
u.stop |
(*Subsystem).discoveryReader |
internal/component/l2tp/pppoe/subsystem.go |
a stop channel this work added, it had none |
rsReaderLoop |
internal/component/l2tp/ppp/ra_linux.go |
ctx.Done() |
dhcpv6ServerLoop |
internal/component/l2tp/ppp/dhcpv6_linux.go |
ctx.Done() |
Three counters, one per package, because ppp cannot import pppoe or l2tp:
ze_l2tp_listener_read_errors_total, ze_pppoe_discovery_read_errors_total, and
ze_ppp_reader_errors_total with a loop label. Each binds through
registry.InjectPluginMetrics, never GetMetricsRegistry.
Verified: go vet clean on darwin and GOOS=linux, -race green across the l2tp
tree and the pacer, and a third ./le go lint run showing zero findings on
these files.
Phase 5, item 1, and it needs a judgement rather than an edit. waitForPADO and
waitForPADS (internal/component/l2tp/pppoeclient/dialer.go) poll with a
runtime.Gosched() in a select default arm. The spec's AC-9 says make the read
block instead. The spec may be wrong here and the agent was told to say so: the
socket carries SO_RCVTIMEO at roughly 100ms, so a blocking read cannot check
stopCh more often than that, trading a bounded busy poll for a slower stop. Unlike
the other four, this loop is already bounded by discoveryTimeout. Read
tryReadPADO and the socket setup, decide, and record the tradeoff. dialer.go is
already modified and dialer_test.go is untracked: that is this spec's own killed
phase 5, not another session's work. Read the diff before continuing it.
Phase 5, item 2. TestReadLoopAllocationsPerPacketUnchanged, for AC-8.
readLoop builds its slot pool, free channel and release closures once at goroutine
start, and the pacer was designed to hold that. An allocation assertion over the read
path, not a benchmark nobody reads.
Phase 6. The functional scenario for AC-1: a socket in a persistently failing
state leaves CPU low while the log and the counter show it. The spec calls it
subscriber-reader-failing-socket. test/qemu/ does not exist, so find the right
suite directory, and add the name to netnsSelections in
internal/le/test/qemu/netns_linux.go. That list is explicit: validateNetnsSelection
refuses a named test with no file but never notices a file nobody named, which is how
two netns-link tests under test/plugin/ came to run nowhere.
Then closure, on Opus 5 in a fresh context, through /ze-close.
Three ppp tests are written and cross-compile-verified but never executed:
TestRSReaderLoopPacesAFailingSocket, TestRSReaderLoopStopsPromptlyWhilePacing,
TestDHCPv6ServerLoopPacesAFailingSocket. They are //go:build linux and this host
is darwin. Do not record them as green.
| Decision | Why it is blocked |
|---|---|
| The four generated RFC index files, third deferral | rfc/enrolled.txt, rfc/not-enrolled.txt, ai/RFC-REQUIREMENTS.md, docs/features/rfc-status.md are held back across three closures. ./le rfc index-update is whole-tree, so this session's real corrections are mixed with a Supported row for draft-ietf-idr-bgp-bfd-strict-mode, whose producer is NOT in HEAD. Publishing it would claim conformance for absent code. spec-bgp-bfd-strict is in-progress and no live session holds it, so nothing schedules the refresh. Landing this session's half needs one ./le rfc index-update in the same commit as that untracked summary, which only that abandoned spec's closure can do. RESOLVED 2026-09-11 by session bgp-notation: that spec was picked up, implemented to draft-19 and CLOSED (e756977a67, 10b270ebc3), so its producer IS in HEAD and ./le rfc index-update ran in the closure commit. The four index files no longer carry a claim for absent code, and nothing blocks this deferral now |
| A closed spec came back | plan/immediate/spec-ipv6cp-accepts-and-proposes-a-zero-interface-identifier.md was correctly removed by 3fd87369fb, then rewritten to disk at 12:22 still reading in-progress Phase 5/5. Content is preserved in fd7cd7b44e, so nothing is lost, but the backlog now shows a closed spec as open and /ze-status counts it. NOT deleted: ai/rules/never-destroy-work.md needs your word first |
| The fabricated-citation class | plan/journal/claim-outlives-the-evidence-it-cites.md holds 47 rows, three of them fabricated RFC quotations or non-existent section numbers. This session's own agents attributed "MUST NOT be all zeros or all ones" to RFC 5072 Section 4.1 (that sentence is not in the document) and cited "RFC 5072 Section 3.2" eight times (that section does not exist). All corrected, none remain. The class has earned a deliberate pass, plausibly a gate: a citation naming a section number is mechanically checkable against the RFC text, which would have caught all eight |
RFC5072-4.1-11 |
Ze's own tentative interface identifier does not clear the "u" bit, so Ze sends in its own Configure-Request a value it now refuses to suggest to a peer. Honestly recorded as a {gap}. Roughly two lines now that suggestIPv6CPInterfaceID owns the machinery, but it changes what Ze puts on the wire and owes a tagged test plus a discrimination record. Wants its own spec |
plan/spec-liveness-event-tears-down-bgp-peer.md |
Carried from the previous handover. design, 13 ACs, written 2026-09-07, never reviewed by you. Its event naming is proceeding as liveness / peer-down / keepalive-expired; your phrasing was "tcp failure with IP". Renaming before implementation costs three constants and one YANG grouping name |
Written this session from your ask for per-user traffic reporting like accel-ppp's.
Both are design, both uncommitted, and you chose the two-spec split and all four
surfaces.
plan/immediate/spec-pppoe-subscribers-produce-no-accounting-or-telemetry.md is
the dependency and the smaller surprise. The collection already exists and works:
iface.GetStats reads per-session pppN netdev statistics, baseline-corrected by
(*baselineStore).applyBaseline, feeding RADIUS accounting, a Prometheus poller and
one CLI command. It reaches L2TP only, because (*radiusAcct).subscribeEventBus
subscribes to l2tpevents while PPPoE emits subevents, and (*Subsystem).Start
builds the poller over the L2TP reactor list. subscriber.Session already carries
AccessType and PppInterface, so there is no new collection to build: the fix is to
consume the shared layer. It also repairs a fail-open, where a failed stats read
appends Acct-Input-Octets = 0 and a billing system cannot tell that from an idle
subscriber.
plan/immediate/spec-subscriber-utilisation-has-no-operator-view.md is the views:
counters on show subscriber, a per-session form, web and gNMI. Two defects it also
closes: show l2tp session id's YANG help promises traffic counters that
sessionJSON never emits, and the one command that does show counters has no
per-session form because its YANG container declares no id leaf.
This host cannot run the interop or QEMU labs. Docker's kernel carries no pppoe
module (host kernel missing PPPoE requirements: pppoe (PPPoE pppox kernel module))
and ./le test qemu pppoe-test exits 1 with qemu guest evidence requires Linux. Four
scenarios and four .ci tests were written across this session's specs and NONE has
ever executed. They are honest, registered, and unproven. A Linux host with PPPoE
kernel support is what they owe. Do not weaken them to reach green.
Two interop scenarios cannot pass even on Linux, and that is correct.
ipv6cp-zero-identifier and ipv6cp-missing-option fail fast with
errIPv6CPNeverEngaged because IPv6CP is unreachable in a shipped daemon:
poolPlugin.handle declines every non-IPv4 family and runNCPPhase sets
disableIPv6CP before any client frame arrives. plan/spec-l2tp-ipv6-subscriber.md
is what switches the path on, and its text now names running them.
The IDE diagnostics in this harness are consistently stale. Seven times this
session they reported undefined symbols or unused functions that a real go vet
showed clean, because they snapshot a mid-edit state. Verify with the registered
action before acting on one.
Lint waves need distinguishing, not dismissing. A cache entry not found wave
across unrelated stdlib imports is shared-machine build contention: check
df -h cache/go-cache, naming the cache path rather than the checkout, since
cache/ symlinks onto another filesystem. (Corrected 2026-09-13: this said
stat -f, which on macOS is a format flag and prints the path back.) But one wave this session was genuinely the agent's own code
(cross-platform unused symbols, an unchecked type assertion, UK spellings), and
treating it as noise would have shipped four defects.
pretool-writeedit refuses a line-number citation in spec prose. Cite the file
and the symbol. It also locks a test body once an RFC requirement: tag is added,
including a tag the same session just added and wants to remove, which is recorded in
plan/learned/HOOK-FRICTION.md with the narrower fix.
./le rfc discriminate-record ... route revert needs no mutation tool. One agent
concluded its tags could not get records because gomu is absent; that is wrong.
rfc/discrimination/rfc2516.json and rfc5072.json are worked examples.
./le spec release, then claim the backoff spec.- Read the diff in
internal/component/l2tp/pppoeclient/dialer.goand the untrackeddialer_test.go. That is the killed phase, and the blocking-read question in section 3 is unanswered. - Finish phases 5 and 6, then
/ze-closeon Opus 5 in a fresh context. - Take the section 4 decisions to Thomas before, not after: the RFC index files have now waited through three closures and the debt is compounding.
Stopped on request. Nothing is half-committed and nothing is lost: 20 commits landed, two specs closed with two commits each, and the three open specs each have their product work in HEAD.
The session's task was to pick specs from plan/immediate/ that no other live
session was editing, and work them. The conflict map at the start was
internal/le/commit, internal/component/config, sysrib, the BGP attribute
path and the plugin host, so the picks were internal/plugins/ packages nobody
held.
Closed, spec file removed:
spec-vrrp-deferred-accept-mode-dataplane(aa7dbfbc6,87c62ff6f). accept-mode is enforced on the dataplane and a tracked interface's failure lowers the advertised priority. Proven on the wire and against keepalived 2.3.1.spec-policyroute-interface-list-matches-no-packet(841e31bb9,2d74298fa). An interface leaf-list ORs, and its per-interface counter rows stay separate.
Product work in HEAD, spec still open: OSPF auto-cost (aca27077f, 4b9e49342,
db3f18b0b, 5a9522302), ddos local max-mitigation-duration (80ec03b03,
4008c0c98, b11fa5c23, d7104cb7b, c23134ce1).
CLOSED on 2026-09-12: spec-ipsec-dataplane-inspection (13ebb566e,
b9f7cadeb). Section 2 below is spent for that spec and is kept only as the
record of what it was waiting for.
spec-ospf-auto-cost-reference-bandwidth — closest to done. Three review
rounds, now 0 BLOCKER and 0 ISSUE. All that remains is /ze-close: the AC walk,
./le spec review record, the learned summary, then the two closure
commits. The session claim is already on this spec.
spec-ddos-timing-leaves-reach-no-worker — one open BLOCKER. Round 5 found
clearStaleDropRule runs before the FIREWALL engine is configured, not merely
before ddos-local is: only the handshake is tier-ordered (runPluginPhase,
internal/component/plugin/server/startup.go), so ApplyAll autoloads the nft
default. On a firewall { backend vpp; } box the sweep clears an nftables table
that never held the rule while the VPP drop survives, and the guide says the rule
is removed "whatever put it there". The reviewer's fix shape is to move the call
to the head of ddos-local's OnConfigure, where the tier order does put the
firewall engine ahead; verify that at runPluginPhase before relying on it. The
round 5 section is at tmp/session/2026-09-08-0a21e591-.../scratch/round5-review-gate.md
and is NOT yet in the spec. Its ISSUE 27 goes with it: the guide's exposure table
is wrong in both directions, since a cold p99 cache leaves PPS detection undelayed
while a never-run box has no armed BPS trigger for about 390 seconds.
spec-ipsec-dataplane-inspection — SPENT, closed on 2026-09-12. What this
section asked for was done. The two .ci (test/ipsec/ipsec-show-dataplane-kernel.ci,
ipsec-show-sa-counters.ci) and the dataplane-readback strongSwan scenario ran
on 2026-09-11, each red with ListSAs emptied and green restored, in a QEMU
guest on the runtime kernel. The two AC-2 repairs the closure review found were
walked red and green on 2026-09-12, and the whole change landed at 13ebb566e
with the spec removed at b9f7cadeb.
- 2026-09-09, OSPF re-price. A
reference-bandwidthcommit must NOT tear down established adjacencies. Implemented indb3f18b0b. Removing the restart alone would have been wrong: origination for a re-pricing only ever happened as a side effect of the neighbor churn the restart caused, soreconcilehad to originate explicitly. - 2026-09-09, ddos on shutdown. In his words: no claim on shutdown, the rule is
not saved because a reboot may be how an operator clears state, and the attack is
re-detected and re-instantiated on the next start. Implemented in
c23134ce1. - 2026-09-08, RFC-tagged test. He approved the arity-only edit to
TestOwnerAutoDetection; the row istest/rfc-changed/ff31c770.md.
Open for him, asked and unanswered: an interface's own cost leaf still
restarts that interface, so ze gives two different answers to what a cost change
costs. Extending the ruling is not a one-liner: reconcile's re-pricing arm never
writes e.running, and lsdbTopology prices from that map.
Every spec in this sweep was already believed done by an earlier session, and every one of them was wrong in a way only an independent round found. ddos took five rounds and each returned a real BLOCKER, all of the same class: an nftables drop rule left in the kernel with nothing able to remove it, reached by a config apply, by a config-block deletion, by the fix's own dispatch race, and by a restart.
The reviews were also wrong twice, and both times the implementer caught it by
reading the producer: the round-2 diagnosis of the removal path (the removal DOES
reach the plugin, as an empty body), and the round-3 placement of the retirement
flag (inside adoptMitigation, past an early return that skips idle responders).
Do not apply a review's suggested patch without checking it.
Tests that passed for the wrong reason, three times. ddos-local-config-removed.ci
passed against code that withdrew nothing, because stopping ddos-local orphan-stopped
the firewall engine, which flushes every ze-owned table: it needs a copp block so a
second dependent keeps the engine alive. policy-interface-list.ci could not fire its
rejections with one rule, because the reverted code still produced one rule. The ddos
clear-arm test read status() rather than the firewall. Force the red before trusting
any of it.
Journal rows this session added, each verified at the producer:
zero-value-as-valid-answer.md—emitClearedbuilds everyAttackClearedwith an emptyDstPrefixandfinalizematches on it, so an incident opened with a resolved victim never closes. Second ddos row in that class.counter-counts-the-wrong-packets.md—applyChainprepends the counter ahead of the term's matches, so every rule in a chain counts every packet the chain sees. Measured: adummy0rule reported the same 3 packets thelorule alone matched.one-members-bad-input-fails-every-member.md— a bareinterface "*"leaves an empty name,lowerIfaceMatchrefuses it, andApplyAllbatches every owner, so copp, ddos-local, flowspec-firewall and the operator's own firewall block all lose their reconcile over one policy-route typo.gate-excludes-part-of-its-population.md— the ddos stale-table sweep needs the plugin to start, so deletingddos localand restarting underflush-on-shutdown falsekeeps the table.ze_flowspec,ze_anomaly-shapeandze_coppsit in the same position; the repair belongs to the firewall engine.late-write-lands-on-the-successor.md— two rows: OSPF'sInterfaceDownstarts a goroutine nothing joins (14 race detections at HEAD, 12 with the change), and the plugin server'sdispatchsnapshots handlers before invoking, which is the durable half of the ddos retirement fix.balance-assertion-vacuous-without-a-loan.md—checkChildRekeyandcheckResponderRaisesChildRekeyboth return nil on an empty baseline SPI set, so the rekey assertion passes vacuously in two scenarios that are green today.component-rebuilt-during-reload.md—ddos flowspechas the identical config-apply orphan the local half was fixed for, and copp has the defect it was cited as the cure for.
docs/features.md was the one real collision. It carried an unlanded
Per-protocol FIB withholding row while my VRRP line was a false RFC 9568
conformance claim. Holding the file would have left the false claim standing, so
after asking, the row rode along disclosed by name in fed8cb495. That session has
since landed (000e70eec) and the row is no longer a forward reference.
The tree-wide red belongs to other sessions and varies by build flavor: an
internal/core/bgp/asn import neither committed nor vendored, updateDelayEndOfRIB
in the distro and appliance flavors, a changed Insert signature against the rib
test files. Name whichever your flavor hits in a structural-red-ok reason rather
than inheriting one from a report; a go vet under one tag set says nothing about
the flavors the gate compiles.
About 18 GB was freed: 33 pre-today session scratch directories and 103 stale
bin/le-* builds.
./le spec release, claimspec-ospf-auto-cost-reference-bandwidth, and run/ze-closeon it. It is one audit away from done.- Claim the ddos spec, paste the round 5 section into its Review Gate, fix the BLOCKER and correct the exposure table, then run round 6 and close.
Claim the ipsec spec and RUN its three artifacts.Done. The spec closed on 2026-09-12 at13ebb566eandb9f7cadeb.- Put the
costleaf question to Thomas when the OSPF spec closes, not later.
SPENT, 2026-09-11. The closure finished and the three files landed; see section 10.
/ze-close ran on spec-ospf-auto-cost-reference-bandwidth and was stopped
mid-phase, out of budget. It had passed the audit steps and was inside its own
Review Gate, fixing what that gate found: its last words were "the
deferred-origination method and the shutdown ordering".
Uncommitted and INCOMPLETE, left in the working tree deliberately:
internal/plugins/ospf/instance.go, instance_test.go, virtual_link.go. Do
not assume they compile and do not commit them as they stand. Read the diff
first and decide whether to finish the fix or drop it; SetCost and everything
db3f18b0b landed are intact in HEAD, so dropping it costs nothing already
proven.
Other sessions' files in that package, to leave alone: bfd_client.go,
asn_notation_test.go, rfc5882_shared_key_test.go.
So the OSPF spec is NOT closed. Its rounds 1 to 3 are clean and recorded, and
a fourth round was in progress and had found something. Restarting means
re-running /ze-close from step 5, not from the top: the deliverables,
documentation and security steps were done, and the round-4 finding is the only
open thread. The session claim is still on this spec.
Everything in sections 1 to 7 above is unchanged and still accurate.
This file holds TWO sessions' handovers. The VyOS-derived subscriber work is
sections 1 to 7 of the first document; the OSPF and spec-closing work is the
second, from "## 1. What landed" onward. They do not overlap. Commit 8760c0623
carried both because the file was edited by both before it landed, which is worth
knowing if the attribution in that commit body reads thin.
Everything that stood on its own is now COMMITTED. The first document says the fourth spec is uncommitted work; that is no longer true.
| Commit | Contents |
|---|---|
300a7541a |
internal/core/pacer, all four receiver loops paced, logged and counted, the client's discovery wait, docs, tests, three journal rows, the spec |
8760c0623 |
The two per-subscriber-usage specs, and this file |
Phase 5 is DONE, not owed. The first document's "Owed, phases 5 and 6" section is stale on both its items. The killed agent had already finished them:
- Item 1 answered the judgement call rather than following the spec blindly.
SO_RCVTIMEOalready blocks the client's discovery read for around 100ms, soruntime.Gosched()was a yield sitting on top of a wait that existed. It removed the yield, addedreadDiscoveryFrameas a package variable so a test can swap the read, and documented the reasoning indocs/architecture/l2tp/cpe-1-pppoe-client.md. - Item 2 exists:
TestReadLoopAllocationsPerPacketUnchangedinlistener_test.go, andTestWaitForPADOBlocksRatherThanSpinsindialer_test.go. Both pass.
All three items below are settled, and the closure is committed. Item 1 was
attempted, found unreachable under ptrace, and then reached on 2026-09-11 through
a seccomp filter: see test/l2tp/subscriber-reader-failing-socket.ci, which the
l2tp suite gates and whose header carries both sets of numbers. Item 3 is
answered rather than recorded: the three ppp tests now RUN, on kernel 7.2 in the QEMU guest, and two
of them carry an observed red there. The original text stands below as the record
of what was asked for.
- Phase 6, the functional scenario. AC-1: a socket held in a persistently
failing state leaves CPU low while the log line and the counter show the failure.
The spec calls it
subscriber-reader-failing-socket.test/qemu/does not exist, so pick the suite directory from what does, and add the name tonetnsSelectionsininternal/le/test/qemu/netns_linux.go. That list is explicit:validateNetnsSelectionrefuses a named test with no file, but never notices a file nobody named, which is how twonetns-linktests undertest/plugin/came to run nowhere at all. - Then
/ze-close, on Opus 5 in a context that did not write the code. - The Goal Validation table must record that three
ppptests are written and cross-compile-verified but never executed: they are//go:build linuxand this host is darwin. Do not mark them green.
Both are in HEAD at 8760c0623, both design, and Thomas approved the split and
all four surfaces. Take them in order; the second depends on the first.
plan/immediate/spec-pppoe-subscribers-produce-no-accounting-or-telemetry.md. The collection already exists and works for L2TP; two consumers simply never moved onto the shared subscriber layer, so a PPPoE subscriber produces no accounting record and no metric. Also repairs a fail-open where a failed stats read sendsAcct-Input-Octets = 0, indistinguishable from an idle subscriber.plan/immediate/spec-subscriber-utilisation-has-no-operator-view.md. The views.
The four decisions in section 4 of the first document all stand. The RFC index one
is the one that compounds: docs/features/rfc-status.md is now three specs stale on
its PPPoE and IPv6CP rows, and the session that could unblock it is gone.
One correction to that section: the resurrected
plan/immediate/spec-ipv6cp-accepts-and-proposes-a-zero-interface-identifier.md is
STILL on disk, untracked, still reading in-progress Phase 5/5, for a spec closed at
3fd87369fb. It makes the backlog show a closed spec as open. Its content is
preserved in fd7cd7b44e, so deleting it loses nothing, but it needs Thomas's word
(ai/rules/never-destroy-work.md).
Commit each finished chunk when it finishes. Three specs closed cleanly, then the
fourth's completed phases sat uncommitted while the session chased the next phase and
ran out of budget. Thomas had to ask whether the work was committed. ai/rules/git-safety.md
already says this: the question after each chunk is whether it stands on its own, not
whether the session is finished.
The Review Gate is where the defects were. Each of the three closures found a
product defect that every implementation phase had missed: a counter that reached no
operator because the registry is created after the component starts, a Session.State
data race from locking two of three accessors, and a fabricated RFC quotation. Budget
closure as defect-finding.
Read the other implementations before designing protocol behaviour. Reading accel-ppp's, FreeBSD's and pppd's own source changed two designs before they were built: the IPv6CP missing-option case would have Naked forever without pppd's one-shot guard, and the PADR dedup would have broken legitimate multi-session CPE without accel-ppp's cookie key. It also caught a false comment in Ze claiming its MAC-keyed dedup matched accel-ppp's, which is cookie-keyed.
The IDE diagnostics in this harness are stale about seven times out of seven. Verify with the registered action before acting on one.
Correction, 2026-09-11: QEMU DOES run on this host. Earlier sections of this
document say it does not, and that is wrong. qemu-system-aarch64 with HVF is
installed and boots. The refusal "qemu guest evidence requires Linux" belongs to the
guest-only ./le test qemu pppoe-test verb, not to QEMU as such. Phase 6 of the backoff
spec discovered this by trying rather than believing the note. The Docker interop
blocker is real and separate: that kernel carries no pppoe module.
The spec is closed and its handoff is gone. These four are not: each was found while doing that work, each is a defect or a false claim in the tree rather than a task somebody abandoned, and each carries a journal row. They are listed here so they are visible to a session reading this file rather than only to one that greps the journal.
| Finding | Where it is recorded |
|---|---|
ASPathEdit.recordAggregator (internal/component/bgp/wireu/aspath_slot.go) does NOT tombstone an AGGREGATOR whose length it cannot read. RewriteASPath did, so the behaviour vanished when Record replaced the whole-payload rewrite, with no red test. The transcode rail still tombstones |
plan/journal/unwired-feature.md |
test/interop/scenarios/bgp-aggregator-as4-downgrade-bird rests on the claim that internal rib alone relays a route to a peer. Measured false twice: the relay is bgp-rs plus bgp-adj-rib-in. The scenario is unverified, not failing, which is worse |
plan/journal/test-against-broken-path.md |
No originating encoder emits an AS4_PATH (internal/component/bgp/message/update_build*.go), so a route ze ORIGINATES carrying a non-mappable AS reaches a two-octet peer as AS_TRANS with the real number nowhere. RFC 6793 Section 4.2.2 requires it |
plan/journal/requirement-met-on-the-rails-the-spec-planned.md |
About 25 RFC tags in internal/core/bgp/attribute/rfc6793_reconcile_test.go carry no discrimination record. They moved there with the rule; only the five added by that work were recorded. ./le rfc discriminate stem rfc6793 lists them |
the retired spec's Work Not Done, in commit b1098e376 |
Two decisions from that work that a later session should not re-open: a lone AS4_AGGREGATOR is DROPPED (the RFC does not cover the shape, FRR keeps and fabricates, BIRD drops, ze takes BIRD's answer), and the tombstone draft-mangin Section 5.3 egress clear is REMOVED. Both are Thomas's, 2026-09-09, and both are documented at the producer as well as here.