final cleanup

3aafbd2 · gmorell · 2026-11-02 02:00

9 files +99 -65

Files changed

modified content/presentations/a-history.md
+13 −14
@@ -1,6 +1,6 @@
1 1 +++
2 2 title = "A History"
3 −description = "How I got here: thirteen years of building backends, platforms and embedded systems"
3 +description = "How I got here: 15+ years of building backends, platforms and embedded systems"
4 4 date = 2026-11-01
5 5 +++
6 6
@@ -33,6 +33,8 @@ show_in_pdf entries. Needs a pass for tone and cuts.
33 33
34 34 BS in Electrical and Computer Engineering
35 35
36 +Note: Picked up python because PHP was banned.
37 +
36 38 ---
37 39
38 40 ## Gecko Health Innovations
@@ -45,7 +47,7 @@ through reminders and monitoring
45 47 - Django on AWS EC2, provisioned end-to-end with Ansible
46 48 - One secure API for iOS, Android and web clients
47 49 - Targeted <100 ms, averaged ~60 ms
48 −- Real-time feedback via Celery + push notifications
50 +- Real-time feedback via push notifications
49 51
50 52 --
51 53
@@ -67,7 +69,7 @@ through reminders and monitoring
67 69 EdTech: improving outcomes for students
68 70
69 71 - Moved the Meteor/Mongo prototype onto Python/Postgres
70 −- Partner data import and export over SFTP
72 +- Partner data import and export over SFTP / CRM APIs
71 73 - Designed the first public API
72 74 - Statistical tooling to measure the platform's impact
73 75
@@ -107,12 +109,12 @@ Solar-powered digital kiosks
107 109 Edge hardware for the factory floor
108 110
109 111 - Rewrote the embedded Elixir product in Rust: **~90% less CPU, memory, disk and startup time**, same API
110 −- Yocto Linux: wireless and driver support on hardware already shipped
112 +- Yocto Linux: improved wireless and driver support on hardware already shipped
111 113 - Containerized third-party workloads (FlowFuse / Node-RED) at the edge
112 114 - OpenTelemetry metrics in place of pulling logs off devices by hand
113 −- Per-customer rate limits and quotas: Redis, Kubernetes, Prometheus
115 +- Per-customer rate limits and quotas: Redis & Prometheus
114 116
115 −---
117 +--
116 118
117 119 ## Now: Cooperative Systems: Spaces
118 120
@@ -128,16 +130,16 @@ Workspace management for makerspaces, hackerspaces and community workshops
128 130
129 131 ---
130 132
131 −## The toolbox
133 +## The Current Toolkit
132 134
133 135 <div class="cols">
134 136 <div>
135 137
136 138 **Languages**
137 −Elixir, Rust, Python, SQL, Kotlin, JS, bash, C, QML
139 +Rust, Elixir, Python, SQL, Kotlin, JS, bash, C, QML
138 140
139 141 **Backend**
140 −Phoenix, Axum, Django, FastAPI, Celery, Twisted
142 +Axum, Phoenix, Django, FastAPI, Celery
141 143
142 144 **Messaging**
143 145 Redis, RabbitMQ, Kafka, Oban, MQTT, WebSockets
@@ -146,13 +148,10 @@ Redis, RabbitMQ, Kafka, Oban, MQTT, WebSockets
146 148 <div>
147 149
148 150 **Infrastructure**
149 −AWS, GCP, Kubernetes, Docker, Podman, Ansible, Argo
151 +AWS, GCP, Kubernetes, Docker, Podman, Ansible, Argo, Git, Postgresql
150 152
151 153 **Embedded**
152 −Yocto, Bitbake, PCB layout (EAGLE/KiCad)
153 −
154 −**Also**
155 −Amateur radio KF5AVL; power tools, rapid prototyping, steel welding
154 +Yocto, Bitbake, PCB layout (EAGLE/KiCad), OTA
156 155
157 156 </div>
158 157 </div>
modified content/presentations/a-summer.md
+47 −1
@@ -1,6 +1,6 @@
1 1 +++
2 2 title = "A Summer"
3 −description = "Today"
3 +description = "of Accelerated Development"
4 4 date = 2026-08-27
5 5
6 6 [extra]
@@ -34,6 +34,8 @@ What I've been upto this summer
34 34
35 35 ## Waxx
36 36
37 +## Devendra
38 +
37 39 ---
38 40
39 41 ## Apollo's Crib
@@ -83,10 +85,19 @@ Now
83 85
84 86 ## Apollo's Palm
85 87
88 +<div class="cols">
89 +<div>
90 +
86 91 Apollo's Crib
87 92
88 93 In Your Hand
89 94
95 +</div>
96 +
97 +![Apollo's Palm showing the weather](/img/apollos-palm.jpg)
98 +
99 +</div>
100 +
90 101 --
91 102
92 103 ## The Hardware
@@ -326,6 +337,41 @@ Live at https://waxx.neiam.co
326 337
327 338 ---
328 339
340 +## Devendra
341 +
342 +Less Ansible
343 +
344 +More Daemon
345 +
346 +--
347 +
348 +## A Tiny Ansible, Embedded
349 +
350 +- Installs config files: quadlets, drop-ins, plain config <!-- .element: class="fragment" -->
351 +- `daemon-reload` only when a unit changed <!-- .element: class="fragment" -->
352 +- Starts, stops, enables, restarts services <!-- .element: class="fragment" -->
353 +- Idempotent: a repeat apply changes nothing <!-- .element: class="fragment" -->
354 +
355 +--
356 +
357 +## Controller → Agents
358 +
359 +- Desired state authored in a small web UI <!-- .element: class="fragment" -->
360 +- Synced to agents over iroh-docs <!-- .element: class="fragment" -->
361 +- Agents pull, converge, and report status back <!-- .element: class="fragment" -->
362 +- Shipped as a .deb, amd64 & arm64 <!-- .element: class="fragment" -->
363 +
364 +--
365 +
366 +## Adopt
367 +
368 +- Point it at a hand-configured host <!-- .element: class="fragment" -->
369 +- It proposes what it finds <!-- .element: class="fragment" -->
370 +- Accept the files you want <!-- .element: class="fragment" -->
371 +- From then on, it's managed <!-- .element: class="fragment" -->
372 +
373 +---
374 +
329 375 # fin
330 376
331 377 ### gmp@gmp.io
modified sass/site.scss
+35 −28
@@ -77,51 +77,58 @@ h1 {
77 77 &:hover { color: var(--base-content); }
78 78 }
79 79
80 −// ── Deck index ───────────────────────────────────────────────────────────────
81 −.decks {
80 +// ── Deck grid ────────────────────────────────────────────────────────────────
81 +.deck-grid {
82 + display: grid;
83 + grid-template-columns: repeat(auto-fill, minmax(min(100%, 22rem), 1fr));
84 + gap: var(--space-md);
85 +
86 + .empty {
87 + color: var(--secondary);
88 + font-style: italic;
89 + }
90 +}
91 +
92 +.deck-card {
82 93 display: flex;
83 94 flex-direction: column;
95 + height: 100%;
96 + min-height: 16rem;
97 + padding: clamp(var(--space-sm), 5vw, var(--space-md));
84 98 border: var(--border) solid var(--base-300);
99 + border-top: 6px solid var(--accent);
85 100 border-radius: var(--radius-box);
86 − overflow: hidden;
101 + background: var(--base-200);
102 + transition: transform 0.15s ease, border-color 0.15s ease;
87 103
88 − li {
89 − display: flex;
90 − align-items: baseline;
91 − gap: var(--space-sm);
92 − flex-wrap: wrap;
93 − padding: var(--space-sm) var(--space-md);
94 − border-bottom: var(--border) solid var(--base-300);
95 − transition: background 0.15s ease;
96 −
97 − &:last-child { border-bottom: none; }
98 − &:hover { background: var(--base-200); }
104 + &:hover,
105 + &:focus-visible {
106 + transform: translateY(-3px);
107 + border-color: var(--accent);
99 108 }
100 109
101 − a {
102 − font-size: 1.0625rem;
110 + h2 {
111 + font-size: 1.75rem;
103 112 font-weight: 700;
113 + line-height: 1.15;
104 114 color: var(--base-content);
115 + margin-bottom: var(--space-xs);
105 116 }
106 117
107 118 .desc {
108 − flex: 1 1 12rem;
109 − font-size: 0.9375rem;
119 + flex: 1;
120 + font-size: 1.0625rem;
110 121 color: var(--secondary);
111 122 }
112 123
113 − time {
124 + footer {
125 + display: flex;
126 + justify-content: space-between;
127 + gap: var(--space-xs);
128 + margin-top: var(--space-md);
114 129 font-family: var(--font-mono);
115 − font-size: 0.8125rem;
130 + font-size: 0.875rem;
116 131 color: var(--accent);
117 − white-space: nowrap;
118 − flex-shrink: 0;
119 − }
120 −
121 − .empty {
122 − color: var(--secondary);
123 − font-style: italic;
124 − &:hover { background: none; }
125 132 }
126 133 }
127 134
modified templates/index.html
+2 −11
@@ -5,15 +5,6 @@
5 5 {{ section.content | safe }}
6 6
7 7 {% set decks = get_section(path="presentations/_index.md") %}
8 − <ul class="decks">
9 − {% for deck in decks.pages %}
10 − <li>
11 − <a href="{{ deck.permalink }}">{{ deck.title }}</a>
12 − {% if deck.description %}<span class="desc">{{ deck.description }}</span>{% endif %}
13 − {% if deck.date %}<time datetime="{{ deck.date }}">{{ deck.date | date(format="%Y-%m-%d") }}</time>{% endif %}
14 − </li>
15 − {% else %}
16 − <li class="empty">No presentations yet.</li>
17 − {% endfor %}
18 − </ul>
8 + {% set pages = decks.pages %}
9 + {% include "_deck_grid.html" %}
19 10 {% endblock content %}
modified templates/section.html
+2 −11
@@ -4,17 +4,8 @@
4 4 <h1>{{ section.title }}</h1>
5 5 <div class="lede">{{ section.content | safe }}</div>
6 6
7 − <ul class="decks">
8 − {% for deck in section.pages %}
9 − <li>
10 − <a href="{{ deck.permalink }}">{{ deck.title }}</a>
11 − {% if deck.description %}<span class="desc">{{ deck.description }}</span>{% endif %}
12 − {% if deck.date %}<time datetime="{{ deck.date }}">{{ deck.date | date(format="%Y-%m-%d") }}</time>{% endif %}
13 − </li>
14 − {% else %}
15 − <li class="empty">No presentations yet.</li>
16 − {% endfor %}
17 − </ul>
7 + {% set pages = section.pages %}
8 + {% include "_deck_grid.html" %}
18 9
19 10 <a class="back" href="{{ get_url(path='@/_index.md') }}">← Home</a>
20 11 {% endblock content %}

Parents: 277408e