Site: security.txt, robots.txt, and favicon fallbacks (ICO, touch icon)
Site / build (pull_request) Successful in 9s

security.txt (RFC 9116) under .well-known with the mailbox as contact and an
expiry in September 2027. robots.txt allows everything and points to the
sitemap. The pixel 9 gets a favicon.ico (32 and 48 px) and an
apple-touch-icon.png, drawn by tools/make_favicons.py from the same
rectangles as favicon.svg.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EhqxQ49eCju4CzKYNjZzwT
This commit is contained in:
2026-10-06 20:12:54 +02:00
co-authored by Claude Sonnet 5.5
parent 821949e3f8
commit 492d8bb187
6 changed files with 73 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
# Security contact for roro9stack.net and the roro9stack firmware (RFC 9116).
# Please report vulnerabilities privately by email, not in the public issue tracker.
Contact: mailto:contact@roro9stack.net
Expires: 2027-09-30T00:00:00.000Z
Preferred-Languages: en, fr
Canonical: https://roro9stack.net/.well-known/security.txt
Binary file not shown.

After

Width:  |  Height:  |  Size: 555 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

+4
View File
@@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://roro9stack.net/sitemap.xml
+2
View File
@@ -10,6 +10,8 @@
<meta name="copyright" content="© 2026 Clément Martin"> <meta name="copyright" content="© 2026 Clément Martin">
{% if current_url %}<link rel="canonical" href="{{ current_url }}">{% endif %} {% if current_url %}<link rel="canonical" href="{{ current_url }}">{% endif %}
<link rel="icon" href="/img/favicon.svg" type="image/svg+xml"> <link rel="icon" href="/img/favicon.svg" type="image/svg+xml">
<link rel="icon" href="/favicon.ico" sizes="32x32 48x48">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="preload" href="/fonts/DMMono-Medium.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="/fonts/DMMono-Medium.woff2" as="font" type="font/woff2" crossorigin>
<link rel="preload" href="/fonts/HankenGrotesk.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="/fonts/HankenGrotesk.woff2" as="font" type="font/woff2" crossorigin>
<link rel="stylesheet" href="/css/site.css"> <link rel="stylesheet" href="/css/site.css">
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env python3
"""Draw the pixel "9" of static/img/favicon.svg as PNGs and an ICO, with the standard library.
python3 site/tools/make_favicons.py
Writes static/favicon.ico (32 and 48 px, PNG inside) and static/apple-touch-icon.png (180 px).
The 9 is a 7x7 grid, scaled by a whole number and centred on the background colour."""
import struct
import zlib
from pathlib import Path
BG = (0x00, 0x00, 0x55)
FG = (0x00, 0xDB, 0xFF)
# x, y, w, h: the same rectangles as favicon.svg
RECTS = [(1, 0, 3, 1), (0, 1, 1, 2), (4, 1, 1, 5), (1, 3, 3, 1), (0, 6, 3, 1)]
GRID = 7
STATIC = Path(__file__).resolve().parent.parent / "static"
def cells():
on = set()
for x, y, w, h in RECTS:
on.update((x + i, y + j) for i in range(w) for j in range(h))
return on
def png(size):
scale = size // GRID
pad = (size - scale * GRID) // 2
on = cells()
rows = bytearray()
for py in range(size):
rows.append(0)
for px in range(size):
cx, cy = (px - pad) // scale, (py - pad) // scale
inside = 0 <= px - pad < scale * GRID and 0 <= py - pad < scale * GRID
rows.extend(FG if inside and (cx, cy) in on else BG)
def chunk(kind, data):
body = kind + data
return struct.pack(">I", len(data)) + body + struct.pack(">I", zlib.crc32(body))
return (b"\x89PNG\r\n\x1a\n" + chunk(b"IHDR", struct.pack(">IIBBBBB", size, size, 8, 2, 0, 0, 0)) +
chunk(b"IDAT", zlib.compress(bytes(rows), 9)) + chunk(b"IEND", b""))
def ico(sizes):
images = [png(s) for s in sizes]
out = struct.pack("<HHH", 0, 1, len(images))
offset = 6 + 16 * len(images)
for s, data in zip(sizes, images):
out += struct.pack("<BBBBHHII", s, s, 0, 0, 1, 32, len(data), offset)
offset += len(data)
return out + b"".join(images)
if __name__ == "__main__":
(STATIC / "favicon.ico").write_bytes(ico([32, 48]))
(STATIC / "apple-touch-icon.png").write_bytes(png(180))
print("wrote favicon.ico, apple-touch-icon.png")