gabe /presentato-ma
public · Issues · Pulls · Labels · Forks · Compare · Actions success · Badges · Packages
⭐
Log in to mark this repository.
final cleanup
3aafbd2 · gmorell · 2026-11-02 02:00
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 | + | |
| 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