This is the multi-page printable view of this section. .
Blog
- 1: Posts
Follow the project through articles, design decisions, and release notes.
1 - Posts
1.1 - Troubleshooting RouterOS DHCPv6 and NetBird's DNS upstream
The goal was to give the LAN behind my home server a working IPv6 egress, and to fix curl -6 and public DNS resolution failing on the server itself.
It turned out to be two consecutive problems:
- RouterOS needed correct DHCPv6 client, Prefix Delegation, LAN RA and IPv6 firewall configuration.
- NetBird had taken over the server’s
/etc/resolv.conf, but no upstream resolver was configured in NetBird Management, so public DNS lookups failed.
RouterOS DHCPv6 client
Initially the MikroTik only received an IPv6 delegated prefix:
The WAN interface never got its own IPv6 address. The fix was to make the DHCPv6 client request both an address and a prefix:
After that RouterOS held two kinds of IPv6:
So the ISP hands out one WAN address plus a prefix that can be delegated to the LAN.
Fixing the LAN bridge address
The LAN bridge had auto-generated a wrong address, 240e:36f:15c3:5cf1::/64, which showed up as duplicate / invalid. The fix was to remove the pool-generated address and generate the bridge gateway address manually:
The bridge ended up correctly as 240e:36f:15c3:5cf1::1/64.
advertise=yes matters — it lets RouterOS send RAs on the LAN so hosts get public IPv6 via SLAAC.
IPv6 firewall
RouterOS already ships a defconf IPv6 firewall. During debugging I temporarily added a duplicate rule set, then removed it and kept the default baseline, making sure the LAN outbound accept sits before the forward drop:
The resulting logic:
A reasonable home-edge IPv6 baseline: LAN can initiate outbound, WAN cannot initiate inbound.
Verifying IPv6 connectivity
At first 2406:4700:4700::1111 didn’t ping, but IPv6 wasn’t entirely broken — these all worked:
And on the server, IPv6 egress was confirmed:
It returned the host’s public IPv6. So: DHCPv6-PD works, LAN RA works, the host has a valid address, and forwarding works.
The DNS problem
With IPv6 egress fine, the plain command still failed:
Not an IPv6 problem — a DNS one.
The server’s /etc/resolv.conf was taken over by NetBird:
100.x.y.z is the server’s own NetBird IP — it was configured to query its own NetBird DNS proxy.
But NetBird Management had no upstream nameserver groups at all (/api/dns/nameservers returned []). So the chain was:
Fixing the NetBird upstream DNS
I created a primary nameserver group via the NetBird API:
With upstreams 1.1.1.1, 8.8.8.8 and 2606:4700:4700::1111. The NetBird API currently limits a nameserver group to 1-3 resolvers, so 2001:4860:4860::8888 didn’t make it in.
After the fix, netbird status -d showed:
Verification:
All passing, and the other mesh peers picked up the same upstreams.
Takeaways
It’s easy to misread this as “IPv6 is broken”, but there were two separate layers:
Debug in layers:
- Use
ping6orcurl --resolveto bypass DNS and prove IPv6 routing works. - Use
dig @specific-resolverto test each resolver. - Only then test plain
curl -6 https://name.
If /etc/resolv.conf is generated by NetBird, don’t stop at the local DNS config — check the DNS Nameserver Groups in NetBird Management too.
Quick rules of thumb:
dig @1.1.1.1works butdig @100.x.x.xfails → NetBird DNS proxy / upstream problemcurl --resolveworks butcurl <name>fails → DNS problem, not routing- RouterOS pings IPv6 but LAN hosts can’t → check RA, bridge address, forward firewall first
Follow-ups
- Keep the NetBird
public-upstream-dnsnameserver group. - Don’t point at a peer’s own NetBird IP as the sole DNS upstream.
- For internal split DNS later, add a dedicated domains nameserver group instead of touching the primary public resolver.
- Maintain the RouterOS IPv6 firewall on top of defconf; duplicate rules just scramble the ordering.
1.2 - Notes on building my own agent framework
After weeks of tinkering and research, this weekend I finally settled on the agent framework I wanted. It started as a Go-based, purely coding-focused agent loop, and ended up as a Python implementation that borrows from bub, Tape System, Kapybara and jido — my own agent framework stitched out of their ideas. The overall approach borrows from bub too.
Declarative design
A lot of it is declarative. Extensibility is arguably the most important property of a framework, and declarative design is what buys it. I took bub’s “everything is a hook” and, per Opus’s suggestion, jido’s state_key-based fused design to keep plugins from getting too fine-grained. Whether it works as intended is still unverified.
Layered memory
The memory part follows kapybara’s design (which is also built on tape): layered, with grounding & getter — the former leaning toward external knowledge bases, the latter toward internal context. I haven’t fully thought this part through myself yet.
Lessons from practice
I rediscovered “Context Engineering from the Inside Out” sitting in my tab bar, and it turned out to be more useful than expected — especially the Failure section. On the point of switching to a better model with higher reasoning effort: when I tested the coding agent loop, gemini 3 flash versus gpt 5.2 or even 5.4, the latter two didn’t show a clear advantage. That could be down to my task design or the code, though. I hit a few other pitfalls too, which I’ll skip here.
Some stray thoughts
In polebug’s latest WeChat article she wrote about over-indulging in vibe coding, and it resonated. Lately I’ve had little urge to record my life at all — my expressiveness feels dulled. I need to rebalance; once this framework is done, it’s probably time for a break.
Maybe next I should figure out what kind of work and life I actually want.
1.3 - 2025 year in review
Time flies — it’s the last day of the year again. A lot happened this year, and I’ve been recording more of it than before. This long-overdue year-end review barely made it onto the 2025 train.
The biggest change is identity: six months ago I stopped being a student, and since then I’ve been tasting the life of a tech worker, overtime included.
A chapter that closed
I spent the first half of the year in a long-distance relationship, grabbing every chance to meet. In the second half, for various reasons, we broke up. Maybe it was always going to end this way.
It took me a while to move on, but I’ve finally accepted it — time to close the door and walk forward.
That relationship is an inseparable part of me. What I can do now is keep the good parts, thank it for how it changed me, and use it to see myself more clearly as I look for a better version of me.
A future I’m still unsure about
Six months into work, minus training, I’ve barely done real work. Honestly, I’m still unsure what direction I should go in. So I’ve been easing into AI at my own pace — from agents to deep learning concepts to LLM inference infra — and joined a few offline community events (Wuhan Cursor meetup, Shanghai Google DevFest, Wuhan DDUC).
The confusion is real. I need to see more of the world: an AI coding hackathon at ModelScope in Hangzhou, a Rust meetup in Shanghai — to find my real goal and meet more people ahead of me. Stay proactive, keep learning, keep the passion.
Growth? Hopes for next year?
My information diet is my main channel and keeps improving.
Technically I can feel myself getting stronger, but I lack output — I want to find a direction I can write about, and a job I actually like.
Make more money! Not for the so-called grown-up checklist, but because money buys freedom. I’d like to learn personal finance, though neither my principal nor my spare time really qualifies.
As for people — it’s been a lonely stretch without someone close to talk to. Flying back to school over New Year’s to see friends sounds like a good idea; hopefully things go smoother after a change of scenery.
All in all, my biggest hope is finding a job I truly want — finding direction, less confusion, some like-minded friends. Romance can wait.
Thanks for the hard work, 2025-me. May next year treat me and everyone kindly. Hello, 2026.
Anime I watched
- Death Note — Kami’s expressions are unforgettable
- Panty & Stocking season 2 — crude, but genuinely good; TRIGGER might be my kind of studio
- Girls Band Cry — dropped it; this genre doesn’t hold me anymore
- Chainsaw Man: Reze Arc — beautiful and hard to let go of; maybe love stories just rarely end well
Games I played
- Stardew Valley — timeless; solo doesn’t appeal, co-op with someone is lovely
- MapleStory — fun early on; forever a nostalgic icon for my generation
- Silksong — lost steam after the early game; my appetite for games is fading
- Hollow Knight — same story; the map grind wore me down — no Dark Souls stamina left