From 652bd652d89eb99f244f9524d6143f207e6b30a9 Mon Sep 17 00:00:00 2001 From: Jarvis Jr Hermes Date: Wed, 22 Jul 2026 19:34:44 +0000 Subject: [PATCH] docs: lead IP records with attribution answer --- address-book/ip-addresses.md | 2 +- address-book/ip/0.0.0.0.md | 4 +- address-book/ip/1.1.1.1.md | 4 +- address-book/ip/TEMPLATE.md | 26 +++++++++++ registry-ips/000-000-000-000--08--iana.md | 4 ++ .../001-000-000-000--16--placeholder.md | 4 ++ .../001-001-000-000--24--placeholder.md | 4 ++ registry-ips/001-001-001-000--24--apnic.md | 4 ++ registry-ips/README.md | 4 +- registry-ips/TEMPLATE.md | 43 +++++++++++++++++++ scripts/validate.py | 18 ++++++++ 11 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 address-book/ip/TEMPLATE.md create mode 100644 registry-ips/TEMPLATE.md diff --git a/address-book/ip-addresses.md b/address-book/ip-addresses.md index d0820f0..5bf13d4 100644 --- a/address-book/ip-addresses.md +++ b/address-book/ip-addresses.md @@ -21,4 +21,4 @@ For every address, investigate these independently: 6. **Infrastructure relationships** — IXPs, facilities, upstreams, cables, and geography where evidence permits. 7. **Time and provenance** — registry and routing facts can change, so every claim needs a source and verification date. -The canonical structured records are in [`data/ip-addresses.csv`](../data/ip-addresses.csv). Range-level knowledge is indexed in [`registry-ips/`](../registry-ips/README.md), using numerically sortable IP-first filenames such as `001-001-001-000--24--apnic.md`. +The canonical structured records are in [`data/ip-addresses.csv`](../data/ip-addresses.csv). Use the [`IP record template`](ip/TEMPLATE.md) for new exact-address pages; its first section must answer **Who is this IP?** Range-level knowledge is indexed in [`registry-ips/`](../registry-ips/README.md), using sortable filenames such as `001-001-001-000--24--apnic.md`. diff --git a/address-book/ip/0.0.0.0.md b/address-book/ip/0.0.0.0.md index b6778f3..32f91ba 100644 --- a/address-book/ip/0.0.0.0.md +++ b/address-book/ip/0.0.0.0.md @@ -1,8 +1,8 @@ # 0.0.0.0 -## Answer +## Who is this IP? -`0.0.0.0` is **not an ordinary public address owned by a company**. IANA records both the exact `0.0.0.0/32` address and its `0.0.0.0/8` parent as special-purpose protocol space. +**Short answer:** `0.0.0.0` belongs to no company or ordinary network operator. IANA reserves both the exact `0.0.0.0/32` address and its `0.0.0.0/8` parent as special-purpose protocol space. | Axis | Finding | |---|---| diff --git a/address-book/ip/1.1.1.1.md b/address-book/ip/1.1.1.1.md index 3ccf705..6cd2ce1 100644 --- a/address-book/ip/1.1.1.1.md +++ b/address-book/ip/1.1.1.1.md @@ -1,8 +1,8 @@ # 1.1.1.1 -## Answer +## Who is this IP? -`1.1.1.1` demonstrates why “owner” must be split into multiple relationships. +**Short answer:** The covering range is registered to APNIC Research and Development, while Cloudflare routes `1.1.1.1` through `AS13335` and operates its public recursive DNS service. This split demonstrates why “owner” must be treated as several relationships. | Axis | Finding | |---|---| diff --git a/address-book/ip/TEMPLATE.md b/address-book/ip/TEMPLATE.md new file mode 100644 index 0000000..d7ae966 --- /dev/null +++ b/address-book/ip/TEMPLATE.md @@ -0,0 +1,26 @@ +# + +## Who is this IP? + +**Short answer:** + +Do not begin with technical background. First answer whose registered resource contains the address, who currently routes it, and who operates the documented service when those are different entities. + +| Axis | Finding | +|---|---| +| Exact address | `
` | +| Registered covering prefix | `` | +| Registry | | +| Registered resource holder | | +| Current announced prefix | | +| Current route origin | | +| Operator/service | | +| Globally routed | | + +## Interpretation + + + +## Sources + +- [Authoritative source](https://example.invalid/), checked diff --git a/registry-ips/000-000-000-000--08--iana.md b/registry-ips/000-000-000-000--08--iana.md index 155c89f..cd5961a 100644 --- a/registry-ips/000-000-000-000--08--iana.md +++ b/registry-ips/000-000-000-000--08--iana.md @@ -1,5 +1,9 @@ # IANA range: 0.0.0.0/8 +## Who is this IP range? + +**Short answer:** IANA reserves this range for protocol-defined “this network” use. It is not assigned to a company, ISP, cloud provider, or ordinary network operator. + - **Registry:** IANA - **Range:** `0.0.0.0/8` - **IANA name:** This network diff --git a/registry-ips/001-000-000-000--16--placeholder.md b/registry-ips/001-000-000-000--16--placeholder.md index 8996bc3..450a93a 100644 --- a/registry-ips/001-000-000-000--16--placeholder.md +++ b/registry-ips/001-000-000-000--16--placeholder.md @@ -1,5 +1,9 @@ # Placeholder: 1.0.0.0/16 +## Who is this IP range? + +**Short answer:** Detailed attribution is not known yet. IANA delegates the encompassing `1.0.0.0/8` block to APNIC, but this placeholder does not assert one registrant, route origin, or operator for the whole `1.0.0.0/16` aggregate. + - **Status:** Placeholder — detailed investigation pending - **Coverage role:** Fills the address-space gap after `0.0.0.0/8` - **Range:** `1.0.0.0/16` diff --git a/registry-ips/001-001-000-000--24--placeholder.md b/registry-ips/001-001-000-000--24--placeholder.md index 8851998..b9a2b9c 100644 --- a/registry-ips/001-001-000-000--24--placeholder.md +++ b/registry-ips/001-001-000-000--24--placeholder.md @@ -1,5 +1,9 @@ # Placeholder: 1.1.0.0/24 +## Who is this IP range? + +**Short answer:** Detailed attribution is not known yet. IANA delegates the encompassing `1.0.0.0/8` block to APNIC, but the exact registrant, route origin, and operator for `1.1.0.0/24` still require investigation. + - **Status:** Placeholder — detailed investigation pending - **Coverage role:** Fills the final range immediately before `1.1.1.0/24` - **Range:** `1.1.0.0/24` diff --git a/registry-ips/001-001-001-000--24--apnic.md b/registry-ips/001-001-001-000--24--apnic.md index 5ea9106..0784107 100644 --- a/registry-ips/001-001-001-000--24--apnic.md +++ b/registry-ips/001-001-001-000--24--apnic.md @@ -1,5 +1,9 @@ # APNIC range: 1.1.1.0/24 +## Who is this IP range? + +**Short answer:** APNIC Research and Development is the registered resource holder; Cloudflare currently originates the route through `AS13335` and operates the documented 1.1.1.1 resolver service. + - **Registry:** APNIC - **Range:** `1.1.1.0/24` - **RDAP name/type:** `APNIC-LABS` / `ASSIGNED PORTABLE` diff --git a/registry-ips/README.md b/registry-ips/README.md index a07c36f..96110a1 100644 --- a/registry-ips/README.md +++ b/registry-ips/README.md @@ -43,7 +43,9 @@ This is **not yet a list of all global ranges**. The expansion plan is in [`rese ## Required contents -Every range file must distinguish: +Use [`TEMPLATE.md`](TEMPLATE.md) for every new range record. The **first section after the title must be `Who is this IP range?`** and must immediately name the registered holder/authority and operator—or explicitly say detailed attribution is unknown. + +Every range file must then distinguish: 1. registry and registered resource holder; 2. special-purpose classification, where applicable; diff --git a/registry-ips/TEMPLATE.md b/registry-ips/TEMPLATE.md new file mode 100644 index 0000000..467d255 --- /dev/null +++ b/registry-ips/TEMPLATE.md @@ -0,0 +1,43 @@ +# : + +## Who is this IP range? + +**Short answer:** + +Do not begin with CIDR mechanics, routing tables, or long background. The first answer must tell the reader whose range this is—or clearly say that detailed attribution is not yet known. + +- **Status:** +- **Registry:** +- **Range:** `/` +- **Registered resource holder:** +- **Observed route origin:** +- **Operator:** +- **Classification:** +- **Globally routed:** +- **Verified:** + +## What is known + + + +## Investigated addresses + + + +## What is not yet known + + + +## Relationship summary + +| Axis | Finding | +|---|---| +| Registration | | +| Registered holder | | +| Route origin | | +| Operator | | +| Service | | + +## Sources + +- [Authoritative source](https://example.invalid/), checked diff --git a/scripts/validate.py b/scripts/validate.py index 444d2d7..d2b0226 100644 --- a/scripts/validate.py +++ b/scripts/validate.py @@ -119,8 +119,10 @@ def main() -> int: ROOT / "docs" / "02-first-round-investigation.md", ROOT / "address-book" / "README.md", ROOT / "address-book" / "ip-addresses.md", + ROOT / "address-book" / "ip" / "TEMPLATE.md", ROOT / "docs" / "04-ip-address-model.md", ROOT / "registry-ips" / "README.md", + ROOT / "registry-ips" / "TEMPLATE.md", ROOT / "registry-ips" / "000-000-000-000--08--iana.md", ROOT / "registry-ips" / "001-000-000-000--16--placeholder.md", ROOT / "registry-ips" / "001-001-000-000--24--placeholder.md", @@ -131,6 +133,22 @@ def main() -> int: if not path.is_file(): errors.append(f"missing required document: {path.relative_to(ROOT)}") + range_records = sorted((ROOT / "registry-ips").glob("*.md")) + for path in range_records: + if path.name in {"README.md", "TEMPLATE.md"}: + continue + headings = [line.strip() for line in path.read_text(encoding="utf-8").splitlines() if line.startswith("## ")] + if not headings or headings[0] != "## Who is this IP range?": + errors.append(f"{path.relative_to(ROOT)}: first section must be '## Who is this IP range?'") + + address_records = sorted((ROOT / "address-book" / "ip").glob("*.md")) + for path in address_records: + if path.name == "TEMPLATE.md": + continue + headings = [line.strip() for line in path.read_text(encoding="utf-8").splitlines() if line.startswith("## ")] + if not headings or headings[0] != "## Who is this IP?": + errors.append(f"{path.relative_to(ROOT)}: first section must be '## Who is this IP?'") + if errors: print("Validation failed:") for error in errors: