| name | ipv6-first |
| description | IPv6 is THE first-class citizen. All code, tests, documentation, and configurations MUST be IPv6-first. IPv4 MAY be added only for legacy support as a second-class citizen. |
IPv6-First Development
Overview
IPv6 is the present and future of networking. IPv4 is legacy.
This skill enforces IPv6-first development across all code, tests, documentation, and infrastructure.
Core principle: Design for IPv6. Add IPv4 only when legacy compatibility is explicitly required.
Announce at start: "I'm following ipv6-first principles - IPv6 is the primary protocol, IPv4 only for legacy support."
The Rule
| Protocol | Status | Priority |
|---|
| IPv6 | First-class citizen | Primary, default, required |
| IPv4 | Legacy support | Secondary, optional, deprecated path |
What This Means
Code
def connect(host: str, port: int) -> Connection:
for family in [socket.AF_INET6, socket.AF_INET]:
try:
return _connect(host, port, family)
except OSError:
continue
raise ConnectionError(f"Cannot connect to {host}:{port}")
def connect(host: str, port: int) -> Connection:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect((host, port))
Socket Binding
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM)
sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_V6ONLY, 0)
sock.bind(('::', port))
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('0.0.0.0', port))
Configuration Files
server:
bind: "::1"
server:
bind: "127.0.0.1"
Documentation
## CORRECT: IPv6 first in docs
### Connecting to the Server
Connect using the server's IPv6 address:
ssh user@2001:db8:85a3::8a2e:370:7334
For legacy IPv4 networks:
ssh user@192.0.2.1
---
## WRONG: IPv4 assumed
### Connecting to the Server
ssh user@192.0.2.1
Tests
class TestNetworkConnection:
def test_ipv6_connection(self):
"""Primary test: IPv6 connectivity."""
conn = connect("::1", 8080)
assert conn.family == socket.AF_INET6
def test_ipv4_legacy_connection(self):
"""Legacy support: IPv4 connectivity for older networks."""
conn = connect("127.0.0.1", 8080)
assert conn.family == socket.AF_INET
def test_dual_stack_prefers_ipv6(self):
"""When both available, IPv6 should be preferred."""
conn = connect("localhost", 8080)
assert conn.family == socket.AF_INET6
class TestNetworkConnection:
def test_connection(self):
conn = connect("127.0.0.1", 8080)
assert conn.is_connected()
DNS and Hostname Resolution
def resolve_host(hostname: str) -> list[str]:
addresses = []
try:
for info in socket.getaddrinfo(hostname, None, socket.AF_INET6):
addresses.append(info[4][0])
except socket.gaierror:
pass
try:
for info in socket.getaddrinfo(hostname, None, socket.AF_INET):
addresses.append(info[4][0])
except socket.gaierror:
pass
return addresses
def resolve_host(hostname: str) -> str:
return socket.gethostbyname(hostname)
Environment Variables and Defaults
export SERVER_HOST="${SERVER_HOST:-::1}"
export BIND_ADDRESS="${BIND_ADDRESS:-::}"
export SERVER_HOST="${SERVER_HOST:-127.0.0.1}"
export BIND_ADDRESS="${BIND_ADDRESS:-0.0.0.0}"
Database Connection Strings
DATABASE_URL = "postgresql://user:pass@[2001:db8::1]:5432/mydb"
DATABASE_URL = "postgresql://user:pass@[::1]:5432/mydb"
DATABASE_URL = "postgresql://user:pass@192.168.1.100:5432/mydb"
URL Construction
def build_url(host: str, port: int, path: str = "") -> str:
if ":" in host:
return f"http://[{host}]:{port}{path}"
return f"http://{host}:{port}{path}"
Validation Patterns
IP Address Validation
import ipaddress
def validate_ip(addr: str) -> tuple[str, str]:
"""
Validate IP address and return (normalized_address, version).
IPv6 is preferred.
"""
try:
ip = ipaddress.ip_address(addr)
version = "ipv6" if ip.version == 6 else "ipv4-legacy"
return (str(ip), version)
except ValueError as e:
raise ValueError(f"Invalid IP address: {addr}") from e
def is_ipv6(addr: str) -> bool:
"""Check if address is IPv6 (the preferred protocol)."""
try:
return ipaddress.ip_address(addr).version == 6
except ValueError:
return False
Network Range Validation
ALLOWED_NETWORKS = [
ipaddress.ip_network("2001:db8::/32"),
ipaddress.ip_network("fd00::/8"),
ipaddress.ip_network("10.0.0.0/8"),
ipaddress.ip_network("192.168.0.0/16"),
]
Comments and Naming
When IPv4 is included for legacy support, comment it as such:
server.bind("::", port)
if not ipv6_available:
server.bind("0.0.0.0", port)
primary_address: str
legacy_address: str
ipv4_address: str
ipv6_address: str
Error Messages
raise ConnectionError(
f"Cannot connect to {host}. "
f"Ensure the server is accessible via IPv6 (preferred) or IPv4 (legacy)."
)
raise ConnectionError(
f"Cannot connect to {host}. Check your network connection."
)
When IPv4 is Required
Add IPv4 support only when:
- Interfacing with legacy systems that don't support IPv6
- Required by external API or service constraints
- Explicitly requested for backward compatibility
- Cloud provider or infrastructure limitation (document this!)
Always document why IPv4 is needed:
legacy_endpoint = "http://192.0.2.1:8080/api"
Checklist
When writing network code: