1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
|
# Package buildsystem page — Implementation Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Add a bilingual (EN/IT) Slackware project page, "Package buildsystem", that narrates the whole slackware64-current build pipeline and links out to the tools that compose it.
**Architecture:** Reuses the existing Slackware project-page schema (front-matter + freeform markdown, filename-inferred thumbnail/header images, `[menus.main]` under the `slackware` parent). Content-only change: no templates, no new Tailwind classes, no CSS rebuild. Pipeline-narrative body in 9 sections. Two crop-derived images per language folder.
**Tech Stack:** Hugo (extended), markdown content, ImageMagick for image crops.
**Design spec:** `docs/superpowers/specs/2026-07-04-buildsystem-page-design.md`
**Reference page (match its voice/conventions):** `content/en/slackware/mkhint/index.md`
---
## File Structure
- Create: `content/en/slackware/buildsystem/index.md` — English page (front-matter + body)
- Create: `content/it/slackware/buildsystem/index.md` — Italian page (translated body, same structure)
- Create: `content/en/slackware/buildsystem/thumbnail.jpg` — 900x600, 3:2, hub row image
- Create: `content/en/slackware/buildsystem/header.jpg` — 1920x480, wide banner
- Create: `content/it/slackware/buildsystem/thumbnail.jpg` — copy of EN thumbnail
- Create: `content/it/slackware/buildsystem/header.jpg` — copy of EN header
- Create: `content/en/slackware/buildsystem/buildsystem-flow.svg` — pipeline flowchart (theme palette + fonts)
- Create: `content/it/slackware/buildsystem/buildsystem-flow.svg` — copy of EN SVG
Image source: `/usr/share/wallpapers/cyan-02-1600x900.png`. Flowchart derived
from the approved artifact design (theme purple/green, Oxanium/JetBrains
Mono/IBM Plex Sans), self-contained dark panel so it reads on both page themes.
Displayed via the existing `image` shortcode (plain `<img>` wrapper), placed
right after the intro paragraph, before `## The VM`.
All work on `master` in the content repo (no theme submodule change). Small/medium content change → work directly on master per project workflow.
---
## Task 1: Create the two image crops
**Files:**
- Create: `content/en/slackware/buildsystem/thumbnail.jpg`
- Create: `content/en/slackware/buildsystem/header.jpg`
- [ ] **Step 1: Make the target directory**
```bash
cd /home/danix/Programming/GIT/danix.xyz-hacker-theme
mkdir -p content/en/slackware/buildsystem content/it/slackware/buildsystem
```
- [ ] **Step 2: Crop the 3:2 thumbnail (900x600)**
Source is 1600x900. `-resize` to cover 900x600 then center-crop with `-gravity center -extent`.
```bash
convert /usr/share/wallpapers/cyan-02-1600x900.png \
-resize 900x600^ -gravity center -extent 900x600 -quality 88 \
content/en/slackware/buildsystem/thumbnail.jpg
```
- [ ] **Step 3: Crop the wide header (1920x480)**
```bash
convert /usr/share/wallpapers/cyan-02-1600x900.png \
-resize 1920x480^ -gravity center -extent 1920x480 -quality 88 \
content/en/slackware/buildsystem/header.jpg
```
- [ ] **Step 4: Verify dimensions**
Run: `identify content/en/slackware/buildsystem/thumbnail.jpg content/en/slackware/buildsystem/header.jpg`
Expected: `... JPEG 900x600 ...` and `... JPEG 1920x480 ...`
- [ ] **Step 5: Copy images into the IT folder (identical crops)**
```bash
cp content/en/slackware/buildsystem/thumbnail.jpg content/it/slackware/buildsystem/thumbnail.jpg
cp content/en/slackware/buildsystem/header.jpg content/it/slackware/buildsystem/header.jpg
```
- [ ] **Step 6: Commit the images**
```bash
git add content/en/slackware/buildsystem/thumbnail.jpg content/en/slackware/buildsystem/header.jpg \
content/it/slackware/buildsystem/thumbnail.jpg content/it/slackware/buildsystem/header.jpg
git commit -m "content: add buildsystem page images (cyan-02 crop)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"
```
---
## Task 2: Write the English page
**Files:**
- Create: `content/en/slackware/buildsystem/index.md`
- [ ] **Step 1: Write the full English page**
Write exactly this file:
````markdown
+++
title = "Package buildsystem"
tagline = "How I build and publish my personal slackware64-current package repository."
status = "active"
tags = ["slackware", "slackrepo", "packaging", "buildsystem"]
[menus.main]
name = "buildsystem"
parent = "slackware"
weight = 20
+++
My personal Slackware packages for **slackware64-current** are built by a small
pipeline of tools running inside one dedicated QEMU virtual machine. Nothing here
is a single program: it is a repository that gets reassembled, a dependency layer
that gets patched, a builder that turns SlackBuilds into packages, and a
publishing step that puts them online at
[packages.danix.xyz](https://packages.danix.xyz). This page walks the whole flow
in the order a build actually happens.
## The VM
The buildsystem lives in a QEMU virtual machine running **slackware64-current**,
kept up to date with `slackpkg` against a local mirror of Slackware's own system
packages. It has 8 CPU cores and around 8 GB of RAM, enough to build all but the
heaviest packages comfortably, and I reach it over SSH. Keeping it in its own VM
means a build, a broken dependency, or a full repository regeneration never
touches my daily driver: the box exists to be hammered and, if needed, thrown
away and rebuilt.
## Assembling the repository
Once a week the SlackBuilds tree is regenerated from scratch. It starts as a
clone of [Ponce's slackbuilds](https://github.com/Ponce/slackbuilds) checked out
on the `current` branch, the community tree that tracks SlackBuilds.org against
slackware-current. On top of that I overlay my own two collections as squashed
git subtrees: [my-slackbuilds](https://github.com/danixland/my-slackbuilds) for
general personal packages and
[Slackware-Pentesting-Suite](https://github.com/danixland/Slackware-Pentesting-Suite)
for security tooling.
Where a personal package shares a name with an upstream one, the upstream copy is
*shadowed*: its directory is removed so my version wins. The result is a single
local tree that is standard SBo plus my additions, ready to build. That whole
assembly is one script, which will get its own page here later.
## The -current dependency problem
SBo SlackBuilds target Slackware **stable**, so some of their build-time
dependencies are unnecessary on -current, which already ships them as system
packages or newer versions. `rust-opt` and `google-go-lang` are typical: needed
on stable, pointless on -current. These "phantom" dependencies would otherwise
force needless rebuilds.
slackrepo strips a dependency from a package with a per-package hint file carrying
`DELREQUIRES`, but writing one by hand for every affected package after each
weekly regeneration is exactly the tedium a script should own. That job belongs to
[mkhint](/slackware/mkhint/): its `-F` sweep reads a list of phantom deps and, for
every package whose requirements hit one, writes or merges the right
`DELREQUIRES` across the freshly rebuilt tree in a single pass.
## Building
The actual building is done by
[slackrepo](https://idlemoor.github.io/slackrepo/), an automated SlackBuild
builder for Slackware. It compiles each package and its dependencies in a clean
chroot, tracks upstream git revisions to work out what has changed and needs
rebuilding, and produces a repository that plugs straight into `slackpkg+`. I run
it with a start hook that first rebases my SlackBuilds tree onto upstream, so
every build starts from a current tree, and it handles the dependency ordering so
a single command rebuilds everything that moved.
## Publishing
When a build finishes, a chain of slackrepo finish hooks takes over. They
regenerate the `slackpkg+` repository metadata, build the styled HTML frontend for
the package site, sync the result out to the live server, and send a notification
that the run is done. The frontend wraps Apache's plain directory autoindex in a
themed header and footer so [packages.danix.xyz](https://packages.danix.xyz) reads
as a proper repository rather than a bare file listing. That frontend is its own
small project and will get a page here later too.
## Testing against 15.0 stable
Some of the packages I write are meant to be submitted upstream to
SlackBuilds.org, which targets Slackware **stable**, not -current. Since my whole
buildsystem is -current, a package building fine here proves nothing about 15.0.
Before I submit one, I test it with a separate, independent tool built for exactly
that: it resolves the SlackBuild's dependency tree locally, then builds and
installs every package in a fresh disposable overlay chroot layered over a clean,
read-only Slackware 15.0 base. That catches the current-versus-15.0 drift a
-current build hides.
It does not touch or drive slackrepo, and its built packages are throwaway: the
only question it answers is "does this still build clean on 15.0". One limit worth
naming: it shares the host kernel, so packages that build kernel modules still
want a real 15.0 VM. This tool will also get its own page here in time.
## The weekly rhythm
Put together, the week is one repeatable cycle: regenerate the SlackBuilds tree,
sweep the phantom-dependency hints with `mkhint -F`, build and publish with
slackrepo and its hooks, and, for anything headed to SlackBuilds.org, spot-test it
against a clean 15.0 base first. Four small tools, each doing one job well, and a
disposable VM to run them in. Very Slackware.
{{< actions use="repo" url="https://packages.danix.xyz" desc="Browse the package repository" caption="Everything the buildsystem produces lands here. If you run slackware64-current, you can point slackpkg+ at it and pull my packages straight in." >}}
````
- [ ] **Step 2: Build the site and verify no errors**
Run: `hugo --quiet --gc`
Expected: exit code 0, no ZgotmplZ or template warnings for the new page.
- [ ] **Step 3: Confirm the page and its images are generated**
Run: `ls public/slackware/buildsystem/`
Expected: `index.html`, `thumbnail.jpg`, `header.jpg` present.
- [ ] **Step 4: Commit the English page**
```bash
git add content/en/slackware/buildsystem/index.md
git commit -m "content: add English Package buildsystem page
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"
```
---
## Task 3: Write the Italian page
**Files:**
- Create: `content/it/slackware/buildsystem/index.md`
Same structure and section order as the English page. `title` stays "Package
buildsystem" (proper noun for the system); `[menus.main]` block is identical
(same literal `name`, `parent`, `weight` so the submenu entry is shared). Body is
translated. No em dashes. Keep every link and the `actions` shortcode identical to
the EN page.
- [ ] **Step 1: Write the full Italian page**
Write exactly this file:
````markdown
+++
title = "Package buildsystem"
tagline = "Come costruisco e pubblico il mio repository personale di pacchetti per slackware64-current."
status = "active"
tags = ["slackware", "slackrepo", "packaging", "buildsystem"]
[menus.main]
name = "buildsystem"
parent = "slackware"
weight = 20
+++
I miei pacchetti Slackware personali per **slackware64-current** sono costruiti da
una piccola pipeline di strumenti che gira dentro un'unica macchina virtuale QEMU
dedicata. Niente qui è un singolo programma: c'è un repository che viene
riassemblato, uno strato di dipendenze che viene corretto, un builder che
trasforma gli SlackBuild in pacchetti e un passo di pubblicazione che li mette
online su [packages.danix.xyz](https://packages.danix.xyz). Questa pagina segue
l'intero flusso nell'ordine in cui una build avviene davvero.
## La VM
Il buildsystem vive in una macchina virtuale QEMU che esegue
**slackware64-current**, tenuta aggiornata con `slackpkg` da un mirror locale dei
pacchetti di sistema di Slackware. Ha 8 core CPU e circa 8 GB di RAM, abbastanza
per compilare comodamente tutti i pacchetti tranne i più pesanti, e vi accedo via
SSH. Tenerla in una VM dedicata fa sì che una build, una dipendenza rotta o una
rigenerazione completa del repository non tocchino mai la mia macchina di tutti i
giorni: quella scatola esiste per essere martellata e, se serve, buttata via e
ricostruita.
## Assemblare il repository
Una volta a settimana l'albero degli SlackBuild viene rigenerato da zero. Parte
come clone degli [slackbuilds di Ponce](https://github.com/Ponce/slackbuilds) sul
branch `current`, l'albero della community che segue SlackBuilds.org su
slackware-current. Sopra vi sovrappongo le mie due collezioni come git subtree
compressi: [my-slackbuilds](https://github.com/danixland/my-slackbuilds) per i
pacchetti personali generici e
[Slackware-Pentesting-Suite](https://github.com/danixland/Slackware-Pentesting-Suite)
per gli strumenti di sicurezza.
Dove un pacchetto personale condivide il nome con uno upstream, la copia upstream
viene *oscurata*: la sua directory viene rimossa perché vinca la mia versione. Il
risultato è un unico albero locale che è SBo standard più le mie aggiunte, pronto
per la build. Tutto questo assemblaggio è uno script, che avrà una sua pagina qui
più avanti.
## Il problema delle dipendenze su -current
Gli SlackBuild di SBo puntano a Slackware **stable**, quindi alcune delle loro
dipendenze di compilazione sono inutili su -current, che le fornisce già come
pacchetti di sistema o in versioni più recenti. `rust-opt` e `google-go-lang` sono
tipiche: servono su stable, sono superflue su -current. Queste dipendenze
"fantasma" costringerebbero altrimenti a ricompilazioni inutili.
slackrepo rimuove una dipendenza da un pacchetto con un hint file per pacchetto che
contiene `DELREQUIRES`, ma scriverne uno a mano per ogni pacchetto interessato
dopo ogni rigenerazione settimanale è proprio la noia di cui uno script dovrebbe
farsi carico. Quel compito spetta a [mkhint](/slackware/mkhint/): il suo sweep `-F`
legge una lista di dipendenze fantasma e, per ogni pacchetto le cui dipendenze ne
toccano una, scrive o unisce il `DELREQUIRES` giusto in tutto l'albero appena
ricostruito, in un solo passaggio.
## La build
La compilazione vera e propria è affidata a
[slackrepo](https://idlemoor.github.io/slackrepo/), un builder automatico di
SlackBuild per Slackware. Compila ogni pacchetto e le sue dipendenze in un chroot
pulito, segue le revisioni git upstream per capire cosa è cambiato e va
ricostruito, e produce un repository che si aggancia direttamente a `slackpkg+`.
Lo eseguo con un hook iniziale che prima ribasa il mio albero di SlackBuild su
upstream, così ogni build parte da un albero aggiornato, e gestisce l'ordine delle
dipendenze in modo che un singolo comando ricostruisca tutto ciò che si è mosso.
## Pubblicazione
Quando una build finisce, subentra una catena di hook finali di slackrepo.
Rigenerano i metadati del repository per `slackpkg+`, costruiscono il frontend HTML
a tema per il sito dei pacchetti, sincronizzano il risultato sul server live e
inviano una notifica di fine esecuzione. Il frontend avvolge il semplice autoindex
delle directory di Apache in un header e un footer a tema, così
[packages.danix.xyz](https://packages.danix.xyz) si legge come un vero repository e
non come un nudo elenco di file. Anche quel frontend è un suo piccolo progetto e
avrà una pagina qui più avanti.
## Test contro 15.0 stable
Alcuni dei pacchetti che scrivo sono destinati a essere proposti a monte su
SlackBuilds.org, che punta a Slackware **stable**, non a -current. Dato che tutto
il mio buildsystem è -current, il fatto che un pacchetto compili bene qui non dice
nulla su 15.0. Prima di proporne uno, lo testo con uno strumento separato e
indipendente pensato esattamente per questo: risolve localmente l'albero delle
dipendenze dello SlackBuild, poi costruisce e installa ogni pacchetto in un chroot
overlay usa e getta stratificato su una base Slackware 15.0 pulita e in sola
lettura. Così emerge lo scostamento tra -current e 15.0 che una build su -current
nasconde.
Non tocca né guida slackrepo, e i pacchetti che produce sono usa e getta: l'unica
domanda a cui risponde è "compila ancora pulito su 15.0". Un limite da segnalare:
condivide il kernel dell'host, quindi i pacchetti che costruiscono moduli del
kernel vogliono comunque una vera VM 15.0. Anche questo strumento avrà la sua
pagina qui col tempo.
## Il ritmo settimanale
Messo insieme, la settimana è un unico ciclo ripetibile: rigenerare l'albero degli
SlackBuild, spazzare gli hint delle dipendenze fantasma con `mkhint -F`, costruire
e pubblicare con slackrepo e i suoi hook e, per tutto ciò che è diretto a
SlackBuilds.org, testarlo prima contro una base 15.0 pulita. Quattro piccoli
strumenti, ciascuno che fa bene un solo lavoro, e una VM usa e getta in cui
eseguirli. Molto Slackware.
{{< actions use="repo" url="https://packages.danix.xyz" desc="Sfoglia il repository dei pacchetti" caption="Tutto ciò che il buildsystem produce finisce qui. Se usi slackware64-current, puoi puntarci slackpkg+ e tirare dentro i miei pacchetti direttamente." >}}
````
- [ ] **Step 2: Build the site and verify no errors**
Run: `hugo --quiet --gc`
Expected: exit code 0.
- [ ] **Step 3: Confirm the IT page and images are generated**
Run: `ls public/it/slackware/buildsystem/`
Expected: `index.html`, `thumbnail.jpg`, `header.jpg` present.
- [ ] **Step 4: Commit the Italian page**
```bash
git add content/it/slackware/buildsystem/index.md
git commit -m "content: add Italian Package buildsystem page
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>"
```
---
## Task 4: Live review
**Files:** none (review only).
- [ ] **Step 1: Start the Hugo dev server**
```bash
hugo server -D
```
- [ ] **Step 2: Check each surface in the browser**
Verify, in both languages:
- Hub row: `http://localhost:1313/slackware/` and `/it/slackware/` — the
buildsystem row appears with its thumbnail (not the mono-glyph fallback), tagline,
and green `active` status badge.
- Single page: `/slackware/buildsystem/` and `/it/slackware/buildsystem/` — the
header banner renders above the title, all nine sections read correctly, every
link resolves (mkhint page link, the three GitHub repos, slackrepo, and
packages.danix.xyz), and the `actions` CTA renders.
- Submenu: the top nav "Slackware" submenu shows the new "buildsystem" entry
alongside "hintfiles helper" and "Packages", and keyboard tabbing into it works.
- Tag pages: `/tags/buildsystem/` exists and lists the page.
- [ ] **Step 3: Stop the server**
Ctrl-C.
- [ ] **Step 4: Report findings to the user and wait**
Do not ship. Summarize what the review showed and hand back to the user for the
go/no-go on deployment (deployment is a separate, user-approved step per the
project git workflow).
---
## Deployment (only after user approval)
Not a plan task. When the user approves shipping, follow the project workflow:
push `master`, then `git checkout production && git merge master && git push origin production`,
and verify the live URLs return 200. The post-receive hook clones the theme and
builds; no submodule bump is needed since the theme is unchanged.
---
## Self-Review
**Spec coverage:**
- Placement/schema (spec §"Placement and schema") → Task 2/3 front-matter + file paths. ✓
- Front-matter fields, no `repo_url`, weight 20 (spec §"Placement") → Task 2/3 front-matter. ✓
- Images from cyan-02, dimensions, both langs (spec §"Images") → Task 1. ✓
- Cross-reference policy: mkhint linked, slackrepo_setup/sbo-batch-tester/repo-html-structure named as future pages (not linked), slackrepo + 3 GitHub repos linked, packages.danix.xyz linked, manage-packages.sh omitted (spec §"Cross-reference policy") → Task 2/3 body. ✓
- 9-section pipeline body (spec §"Body structure") → Task 2/3, all sections present in order. ✓ (Note: spec named section 7 "Testing against 15.0"; both pages use that scope and framing — only my own SBo-bound packages.)
- VM section states cores + RAM, no hostnames/paths (spec §correction) → Task 2/3 "The VM". ✓
- No em dashes (spec §"Style constraints") → checked: bodies use commas/colons only. ✓
- Content-only, no CSS rebuild, hugo --gc exits 0 (spec §"Build / ship flow") → Task 2/3 build steps, Task 4 review. ✓
**Placeholder scan:** No TBD/TODO left. The CTA `use`/`url` are concrete (`use="repo"`, `url="https://packages.danix.xyz"`). ✓
**Type consistency:** Front-matter keys, menu block, image filenames, and link URLs are identical across Task 2 (EN) and Task 3 (IT). ✓
|