Repository navigation
release: promote development to main (academy tutorials + ConNext pivot + partners on app/solution pages) - #118
WilcoLouwerse wants to merge 426 commits into
Conversation
Code Review — PR #118: release: promote development to mainOverviewRelease-merge van Sterke punten
Aandachtspunten1.
|
| Risico | Kans | Impact | Mitigatie |
|---|---|---|---|
| Supply-chain via uitgeschakelde cooldown | laag | hoog | Re-enable vóór merge naar main; verifieer met npm audit signatures |
Stale llms.txt schaadt AI-citaten |
hoog | laag | Sync solution-lijst in dezelfde commit |
/nl/* deep-links 404 na rename |
laag | laag | NL-redirects toevoegen of bewust accepteren |
| Preset 3.3 → 3.20 verbergt regressie | laag | midden | CI dekt het al via build + validator (groen) |
Verdict
Approve onder voorwaarde: re-enable min-release-age (issue #115) en sync static/llms.txt vóór merge naar main. De overige punten zijn nits / opvolg-werk. CI is groen en de auditability is sterk — dit is het soort release-PR dat goed te reviewen blijft ook door iemand die de afgelopen weken niet meekeek.
🤖 Generated with Claude Code
…MCP schema
- objects-tool Notes column: `registerId` / `schemaId` → `register` / `schema`
(integer IDs) to match McpToolsService::getObjectsTool() inputSchema.
- Resource URI template: `openregister://objects/{registerId}/{schemaId}` →
`{register}/{schema}` and `{registerId}/{schemaId}/{uuid}` → `{register}/{schema}/{id}`
to match McpResourcesService::listTemplates() output.
- Discovery JSON description: drop `audit` from the parenthetical capability
list — `audit` isn't a tool, served as object history via the same `objects`
family (as the tutorial itself correctly explains later).
Mirrors EN edits in the NL i18n file.
Resolves all 3 review threads on PR #12.
…ed download total - Replace hand-drawn placeholder app icons with the canonical <AppGlyph> from the preset across the 17 /apps product heroes (auto from appId), the ConNext platform diagram, and the apps-catalogue grid. openanonymiser and app-versions keep inline icons (no canonical glyph yet). - Drop the explicit cobalt iconColor on product heroes so DetailHero renders the orange icon hex on its cobalt background. - Docs links now point at per-app subdomains (https://<slug>.conduction.nl) instead of docs.conduction.nl/<slug>. - Homepage download stat reads the combined GitHub+Codeberg total from the local app-downloads.json (TOTAL_DOWNLOADS), and per-app cards use downloads_total. Collector merges both forges. Fixes the "0 downloads" figure left after the GitHub→Codeberg migration.
…real endpoint, basic-auth, nextcloud.local' (#12) from tutorial/mcp-server-deepdive into development Reviewed-on: https://codeberg.org/Conduction/conduction-website/pulls/12
…trofit playbook' (#15) from feature/tutorial-openspec-retrofit into development Reviewed-on: https://codeberg.org/Conduction/conduction-website/pulls/15
OpenSpec series: - add Part 0 (why spec-first), Part 3 (ADRs), Part 4 (scenario to Playwright) - revise Parts 1-2 (starting point, cross-links, voice) Hydra series: - correct gate count to 22 and builder model to Sonnet (config-authoritative) - add OpenSpec->Hydra contract, supervisor/orchestrator split, hydra.json v2 schema - fix Applier description (read-only go/no-go, no fixes) - new Part 7 (CI and deployment) Site-wide: - rename all Dutch tutorial slugs to English (en + nl) with redirects - strip em-dashes from new content per tutorial-write voice rules
# Conflicts: # academy/2026-05-12-openspec-tutorial-2-eerste-change/index.mdx
The fleet-rename sed pass had rewritten the redirect 'from' values to the new English slugs, turning each into a self-redirect that collided with the real page at build time. from = old Dutch slug, to = new English slug.
…OpenConnector) - Part 3: scope a catalog, the publicatiedatum publish rule, public search, and the DCAT-AP-NL harvest feed (with live screenshots) - Part 4: source, mapping, and synchronisation in OpenConnector that turn an external API into Woo publications (with live screenshots) - Part 2: link its next-steps to the new Part 3
…catalog + OpenConnector)' (#17) from academy/woo-publish-harvest-connect into documentation
The docs build prebuild crashed when an upstream stats API (GitHub/Codeberg/ Nextcloud store) returned 4xx/5xx, blocking every Cloudflare Pages deploy from the documentation branch since 2026-06-11. A download-stats fetch must never break the build: catch network errors, keep the committed data/app-downloads.json stub, and continue.
…ts fetch fails' (#18) from fix/docs-build-app-downloads-resilient into documentation
…T register - Part 1: import Woo and DCAT registers via the OpenRegister UI - Part 2: upload files via the Files panel; API moved to an appendix - Part 3: publish and harvest a DCAT catalog (catalog scope, publicatiedatum publish rule, public search, DCAT-AP-NL feed) via the UI - Part 4: source, mapping, synchronisation via OpenConnector UI; API appendix - Fresh vanilla-Nextcloud screenshots for Parts 1-3 (theming excluded) - Registers hosted on openregister.conduction.nl/oas/
…Parts 1-4) + DCAT' (#19) from academy/woo-series-ui-first into documentation
…art 4 resultsPosition - static/oas/woo_register.json + dcat_register.json: the two register configs the WOO tutorial imports (Part 1). Previously the tutorial pointed at openregister.conduction.nl/oas/ which 404'd and the files never existed. - Part 1: repoint import URLs to conduction.nl/oas/ (deployable here). - Part 4: resultsPosition 'body' -> '_root' (the pet-store endpoint returns a root array; 'body' dot-paths into it and creates zero objects). - bump @conduction/docusaurus-preset ^3.20 -> ^3.22 (adds the AppGlyph the landing pages need). NB: /apps + /connext still use components ahead of the latest published preset, so a full site build is still blocked until that preset publishes.
Two fixes that were blocking the docs deploy and the tutorial UX: 1. AppGlyph build break: connext.mdx and apps-catalog.js imported AppGlyph from @conduction/docusaurus-preset, but that component is not in any published preset release (3.22.0 / 3.22.1-beta.1 both omit it), so the import resolved to undefined and crashed the static render of /connext — failing the whole build. Add a local AppGlyph (token-painted app monogram) and point both importers at it. Drop once the preset ships AppGlyph in a stable release. 2. Tutorial series navigation: the academy uses a custom BlogPostPage that bypasses BlogPostItem, so the preset's BlogPostItem/Footer SeriesNav swizzle doesn't reach it. Render <BlogSeriesNav/> (from the preset) directly after the post body, so every multi-part tutorial (woo, hydra, build-an-app, openspec, workstation, claude-skills) gets a 'Part X of N' strip with prev/next. Requires @conduction/docusaurus-preset with SeriesNav/BlogSeriesNav (^3.22.0 picks it up once published).
…enshots Part 3 (publish-and-harvest) showed the public-search response and the DCAT-AP-NL feed as screenshots of the browser's raw JSON view — an unformatted wall of text. Replace both with Docusaurus (Prism) `json` code blocks: selectable, syntax-highlighted, and diffable. Also corrects a content mismatch: the public-search screenshot showed both datasets (total: 2) under a caption claiming only the published one; the code block now shows the published-only response (total: 1), matching the narrative. The DCAT block mirrors OpenCatalogi's actual DcatMappingService serialisation (dcat:Dataset / dcat:Distribution with dct:* + EU authority URIs for theme and file-type).
Convert the OpenConnector tutorial so each action step (register source, write mapping, create synchronisation, run) offers three synced tabs — UI, API (curl), and PHP — via Docusaurus <Tabs groupId="woo-how">, so a reader picks an interaction style once and it persists across every step. - The old 'Appendix: via the API' is folded into per-step API tabs. - PHP tabs use the apps' real OCA\ services, verified against source: OpenRegister ObjectService::saveObject(object:,register:'openconnector', schema:'source'|'mapping'|'synchronization'), OpenConnector CallService::call(), MappingService::executeMapping(), and SynchronizationService::synchronize(). - Fixes a real bug: the synchronisation's results position for the Pet Store's bare array is '_root', not 'body' (the UI text said 'body'). - Step 5 (schedule) stays UI-only with a note: scheduling is a separate background job, so it has no one-line API/PHP equivalent.
…rg URL 404) The Dutch woo-register tutorial still linked the woo-website Codeberg raw URL, which now 404s. Match the English version: use the live, hosted config at https://conduction.nl/oas/woo_register.json.
! almere voor Acato > Den Haag
…and-input chore(config): roster paths, sitemap scope and a dev watch fix
…ays (#224) The app is installed on the portal and the site sends it nothing, because the plugin is only wired when PORTALIQ_TRAFFIC_ORIGIN is set and production never set it. So there is no measurement, and nothing on either side says so. This adds the variables to the build and a guard that fails the deploy when the two disagree: set the origin and the built pages must carry the traffic client, leave it unset and they must not. A variable that is set but does nothing is worse than one that is unset, because it reads as measurement being on. The guard matches the client route, which nothing else requests, rather than the portal host, which is also the enquiry endpoint and is in the bundle either way. The variable is NOT set in this change, deliberately. The client's own settings call, `/api/content/site?portal=<slug>`, is public on that instance and answers 404 not_found for every slug tried, including none: conduction, conduction-nl, website, www.conduction.nl, main, public, site, connext, portaliq. Other portaliq routes answer 401, so the route is reachable and the portal is what is missing. Turning the site side on now would put a 14KB script on every page whose settings call 404s and which measures nothing. Setting the variable is then the whole remaining change.
…225) * feat(a11y): measure the states a page is in after someone clicks, and whether focus is visible Three of the four gaps I named when asked whether every page had been thoroughly tested. It had not: every result so far described a page as it loads, in Chromium, with no opinion about keyboard users. REVEAL_ALL puts a page into its opened state before measuring: every <details> opened, every aria-expanded=false clicked, every unselected tab and Showcase-style item activated. This is not hypothetical. The colour-role lint flagged badge markup on /quality/ that renders ZERO times as the page loads, because it lives in a Showcase panel that is not defaultOpen, and the runtime sweep had no way to see it. Findings now carry the state they were found in, so "only after opening something" stays distinguishable from "on the page as it loads". FOCUS_CHECK asks two things of each control: does anything change when it takes focus, and if the change is an outline, does it clear 3:1. This was in the September plan and never shipped. On two pages alone it finds focus rings at 1.00:1, which is an indicator the same colour as the thing behind it. The focus check compares what is PAINTED, not the property list. Chromium's UA sheet moves outline-offset from 0px to 1px on a:focus even when the author has set outline:none, so a raw property dump saw a change where a reader sees nothing and the stripped-focus fixture went unreported. An outline with style none or zero width now reads as nothing. WebKit is Safari's engine and therefore most phones, and the suite ran zero percent of it: the mobile project was pinned to chromium on the grounds that layout is engine-agnostic. Largely, not entirely. A mobile-safari project runs the mobile and a11y specs on it. It ships warning-first in CI and I want to be plain about why: WebKit needs system libraries this machine cannot install without sudo, so CI is the first place it will ever execute and nobody knows what Safari says about these pages. Blocking the deploy on an unknown would stop releases for reasons unrelated to the change being deployed. The step prints what it found and the comment says to promote it once it is understood. A warning nobody promotes is the same as no check at all. a11y-interactive.spec.js is the control for both. The reveal test uses a fixture whose defects are all behind a disclosure and asserts the checker finds nothing before opening and both defects after. The focus test asserts that outline:none with nothing put back, and an indicator under 3:1, are each reported, and that a correct indicator stays quiet. * test(a11y): the focus check scores the whole indicator, not just the outline The preset's focus treatment is two rings now: a brand outline plus a halo of the opposite luminance, because no single colour clears 3:1 on every surface this site puts a control on. Judging the outline alone would report that treatment as broken, which is the checker being wrong about a page rather than the page being wrong. It reads the box-shadow rings as well and scores the best of them, since the criterion is met when any part of the indicator is visible. The control gained a case for it: a link on an orange button whose outline is 1.00:1 and whose halo is 5.93:1 must stay quiet. Without this change that case fails, which is what makes it a control rather than a comment.
…ite (#226) 3.49.1 carries the two-ring focus indicator. A focus-visibility check added to this suite measured 1,399 failures on 316 pages, every one an indicator under the 3:1 the criterion asks for, and the site has been pinned one patch short of the fix since it was released. No single ring colour clears 3:1 on every surface here: KNVB orange is 2.68:1 on a cobalt-50 panel and 1.00:1 on an orange button, coral-600 is 1.94:1 on a cobalt hero, white fails on light grounds and cobalt-900 on dark ones. The preset draws two rings now, the brand outline plus a halo of the opposite luminance, and the worst case across those surfaces is 5.93:1. 3.49.0 to 3.49.1 is only that change. The FullStack component the site already uses is unaffected. Verified: build green, colour-role lint reports 0 blocking, the halo is in the built CSS with both theme values, and focus measures clean across 20 page and theme combinations. Full e2e is 272 of 274 at --workers=2; the two failures are "connext lists the renamed apps" and "deadline defender", both of which pass in isolation (2 of 2, twice). The cn-* custom elements upgrade asynchronously and lose that race when this machine is loaded.
) The deploy workflow builds with PORTALIQ_TRAFFIC_ORIGIN set, a guard fails the deploy if the traffic client is missing, and then the e2e suite runs against that same build. So every test that loaded a page posted a real page_view to the production collector, on every deploy, across three browser projects. Measured hours after measurement was switched on: 46 of the 58 events recorded against the ConductionNl portal came from localhost:4173, which is this suite's own preview server. The first day of the site's analytics was three quarters test traffic. e2e/base.js aborts the collector beacon and every spec imports its test from there. Aborting beats pointing the build at a dead origin: the page under test stays byte-for-byte what deploys, including the script tag the guard checks for, and only the beacon is dropped. The settings GET is left alone so the client still runs its real code path and would still fail the suite if it threw. Proven against the live instance, both directions: a full 274-test run leaves the event count at 92, and the same spec with the import put back takes it 62 -> 64. Two of my own game tests came with it, both brittle for the same reason — they encoded copy that the 3.48.0 rework changed: - deadline defender mapped each case's wording to the step it wanted. That map broke twice, most recently because a fourth lane arrived: a case that takes no next step at all is now one of the answers. It asserts the board is dealt and that answering replaces the case; which lane a case belongs in is the engine's own tests' business. - blueprint rush now takes the next flow when the clock beats it, rather than depending on winning the one it was dealt. And one stale test unrelated to any of it: product-names looked for the renamed apps inside `pd-item[name]`, the platform diagram's custom elements. That diagram lists the Nextcloud apps Connext runs on now, and the elements are replaced on hydration, so the selector matched nothing. It asserts the page names them, which is what the rename sweep is actually for. Verified: both locales build, 274 of 274 pass on the gating projects. The 80 mobile-safari failures here are the missing WebKit system libraries this config already documents; CI installs them.
…ger never meets (#228) Closing out the last open items from the mobile and dark-mode review. Three of the four turned out to be the instrument over-reporting rather than site debt, which is worth saying plainly. WebKit is in the gating step now. Its first real run was 79 of 81, and the two were one flake that passed on retry. The single genuine engine difference was a race the drawer test was losing: the link resolves while the drawer is still re-rendering, so the node about to be clicked is replaced under it. Chromium won that race and Safari did not, which is the kind of thing running one engine hides. The test waits for aria-expanded to flip before reaching in, which is the component saying it has settled rather than a sleep. Both engines install in one step now that both gate the deploy; a failed install should look like the infrastructure problem it is, not like a silent gap. target-size was measuring the wrong box. A labelled control's target is the control plus its label, because clicking the label activates it. The filter checkboxes are 16x16 and each has a label[for] of 305x44, so judging the input alone reported 42 failures a finger never experiences. Across eight pages at 390px that is 42 down to 4, and the 4 left are text links whose height is their line-height, which is the grey area the criterion itself carves out. tiny-text said "under 12px" for everything, and 459 of 520 findings on a mobile sample were the brand's 11px uppercase eyebrow. That buried the 61 that are genuinely smaller. Severity is split by size now: below 11px is moderate, 11px is info and named as the convention. The sub-11px text lives in preset game HUDs and card metadata, and raising it is a design decision across every Conduction site rather than a bug fix, so it is reported and not changed. The colour-role lint went from 163 advisory findings to 44. 126 were brand accent colours used as ink, which is their documented job: an accent that followed the theme would stop being the brand. They are excused by value, in a list, with the reasoning, and the runtime sweep reports zero contrast failures for any of them. Two whole-file fixed shells, the cookie terminal and the error page, take a file-level opt-out, which only counts in the header so it cannot be dropped in halfway down to silence something inconvenient. Every change here has a control. The labelled-target case fails without the fix, and --strict now prints every finding instead of the first forty, because capping the output of the show-me-everything mode defeats the point of it. Verified: 273 of 274 at --workers=2. The one failure is planninq's hydration test, which passes 2 of 2 in isolation and took 31.9s under contention.
development is red and this is why. #227 correctly stopped the suite posting page views to the live collector, but it did so with route.abort(), and an aborted request makes the browser log "Failed to load resource: net::ERR_FAILED". space-invaders.spec.js asserts that playing produces no console errors, so it fails all three attempts and reads as a product fault rather than as the suite tripping over its own stub. #227's own run went red the same way. Fulfilling with 204 keeps the intent exactly: the beacon still never reaches the collector. It also keeps the client on its success path, which is what #227 wanted from leaving the settings GET alone, so a client that throws on a real response would still fail this suite. Proven rather than reasoned: against a page that posts to the collector route, abort() produces one console error with exactly the string from the CI log and fulfill 204 produces none. I could not reproduce the failure locally. The beacon only fires when PORTALIQ_TRAFFIC_ORIGIN is configured, which CI has and a local build does not, so the route never matches here and both versions pass. CI is the verification for the end-to-end case; the mechanism above is what I could establish directly. 274 of 274 locally.
…hiding
The a11y gate carried two colours it was told to ignore: Common Ground
yellow cited as text at 1.93:1, and KNVB orange at 2.68:1 on a cobalt-50
ground. The comment said the fix was a brand decision, not an
accessibility one, so the sweep should not make it.
The decision is made, in the design system, from the kit's own rules.
Preset 3.50.2 brings it: both citation classes now read a theme-aware
token, six components that overrode the class follow it, and the cobalt
hero switches its title citations the way its tagline already did.
So the allowlist has nothing left to allow, and it is gone. That is the
point of this change rather than a side effect: with it removed, the
gate fails if either raw colour reaches text again.
Removing it turned up two live defects on the sampled pages, both a
hand-rolled version of something the kit already publishes.
/support/ painted the eyebrow LABEL in KNVB, 2.68:1. The kit's own
Eyebrow primitive colours the label with text-muted and lets the hex
bullet carry the orange. Now it matches. The hex stays KNVB.
/apps/integriq/ painted a tag in KNVB on the coral-50 tint, 2.76:1.
tokens.css already publishes the pair: coral-700 is documented as
"warning ink, 7.89:1 on coral-50". Now it uses it. Both locales.
Note that text-accent alone would NOT have fixed the eyebrow: coral-600
is 4.67:1 on white, which the kit says, but only 4.16:1 on the cobalt-50
panel. A colour is safe against a surface, never on its own.
Verified: 274 of 274 Playwright tests pass on chromium and mobile with
the allowlist removed. WebKit could not launch on this machine, so
mobile-safari runs in CI.
Inherited, reported, not fixed here. The full-site sweep found three
more contrast defects, none on a line this change touches:
8 academy blog posts, figcaption on --ifm-color-emphasis-600, 2.83:1.
text-muted reads 5.01:1 on that panel.
/apps/decidiq/, the WITHDRAWN badge on cobalt-300, 2.69:1.
cobalt-400 reads 4.83:1 on that ground.
/demo/, a comment in the dark code block, 2.84:1.
Each is one line. They belong to a debt sweep, not to this branch.
feat(a11y): retire the brand-citation allowlist, and fix what it was hiding
All three were reported but not fixed in #230, as inherited debt. This closes them. Preset 3.50.3 brings the focus-ring half of the same sweep. Academy figcaptions, 12 declarations across 10 posts. They used Infima's --ifm-color-emphasis-600, which is 2.83:1 on the chart panel. They take text-muted now, 5.01:1 there. The three SVG arrow marks in la-frankendesk keep the old grey on purpose. That post's own caption reads "Blue marks a component that came from an existing project", so pointing its arrows at the muted blue ink would make the figure contradict its legend. They need a neutral darker grey, which the kit does not publish. Left reported. decidiq, the WITHDRAWN badge. cobalt-300 was 2.69:1 on the light panel. It takes text-muted, which is 4.83:1 in light and 8.77:1 in dark. Worth recording why it is the THEME-AWARE token and not cobalt-400. I shipped cobalt-400 first, measured only against the light ground, and verification caught it at 2.89:1 in dark: that panel's surface flips and a fixed ink over a flipping surface is exactly the fault the colour-role lint exists to catch. The lint did not catch this one because the value is an inline style in MDX, which it does not parse. /demo/ code comments. Prism's palenight writes 2.84:1 comments, and this needed two attempts as well. A CSS rule in site.css does nothing here: prism-react-renderer emits every token colour as an INLINE style. The config now passes a palenight variant with only the comment token changed, to #b6c2dd, 7.59:1 on that block and still dimmer than the code. Verified, both themes, directly on each fixed page: 9 pages clear of contrast-severe, and the focus check clear on the partner tiles and the filter chips with its sample limit raised to 400, which covered every control (71/71, 179/179, 68/68). 274 of 274 Playwright tests pass. Left reported: brand.css sets --ifm-pre-background to cobalt-900, and palenight paints over it, so no site renders the kit's intended code-block colour. Retheming every code block is a design decision and belongs in the preset, not in this fix.
design-system #90. HiddenGame's opener button hardcoded a cobalt focus ring, which on a cobalt section is 1.00:1, so the best the indicator managed was the halo at 1.97:1. Measured on /apps/integriq/ in light. It was found by raising the sweep's focus sample limit from 40 to 400. /academy/ has 179 controls, so the default had been visiting under a quarter of them and walking past this one. Verified on the built site, both themes, every control sampled: /arcade/, /nl/arcade/, /apps/integriq/, /apps/openregister/, /academy/ and / are clear of focus-contrast. 274 of 274 Playwright tests pass.
…ects fix(a11y): clear the last three contrast defects the sweep found
…neutral Preset 3.51.1 brings the brand syntax theme (design-system #91), the footer citation fix, and visible focus rings on the mini-game buttons (#92). This side removes the override that would have blocked the first of those, and fixes the one thing left in the academy post. Code blocks. brand.css has always declared cobalt-900 with cobalt-100 code, and no site has ever rendered it: Docusaurus fell back to palenight, which paints its own #292d3e and writes token colours as inline styles. The palenight override added here yesterday raised one token and is now redundant, so it is gone. Verified on the built site: the block is background-color:#0A172F with color:#DCE3F0. The footer citation. Nextcloud's own darker blue was 4.28:1 on the cobalt-900 footer, just under AA, on every page of the site. It is the cyan now, 7.33:1. That single fix removed 88 of the 94 contrast findings across the pages that carry a code block. The la-frankendesk arrows. They were the one thing left from the sweep, reported in #232 as needing a colour the kit does not publish. It does: --c-gray-500. I was wrong about that. The arrows had to stay NEUTRAL because that chart's own caption reads "Blue marks a component that came from an existing project", so a muted-blue arrow would have made the figure contradict its legend. Measured against the real panel in both themes: 4.47:1 light, 3.46:1 dark, both past the 3:1 SC 1.4.11 asks of meaningful non-text. A mid-luminance neutral is what survives a ground that flips. Verified on the built site, both themes: 22 pages with a code block: 0 blocking findings, and 0 findings whose colour is any of the nine syntax tokens arrows rgb(107,114,128), footer citation rgb(28,175,255) focus clear on /apps/integriq/, /academy/, /apps/dossiq/ and /arcade/ with every control sampled (88/88, 179/179, 71/71, 59/59) 274 of 274 Playwright tests pass One note for the next person who touches this: a preset static-asset change does not reach the build until node_modules/.cache is cleared. rm -rf build .docusaurus is not enough, and the stale copy made the footer fix look like a no-op through two clean rebuilds.
feat(code): code blocks render the kit, and the diagram arrows get a neutral
…eplaces the Codeberg SSH + tea step The 2026-05-29 move to Codeberg was reversed (directive 2026-07-17, executed 2026-07-23). Part 2 Step 7 still taught a passphrase SSH key, keychain and tea for a host ConductionNL no longer uses; it now sets up gh auth login over HTTPS with gh as git's credential helper. The Codeberg guide stays linked for Forgejo-only cases, with a fix for the leftover keychain prompt. SSH clone URLs in parts 3, 5 and 6 become HTTPS. EN + NL. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ithub-first docs(academy): workstation tutorial is GitHub-first — gh over HTTPS replaces the Codeberg SSH + tea step
…mages, forge and example repos The 2026-05-29 move to Codeberg was reversed (directive 2026-07-17, executed 2026-07-23), but several tutorials still described Codeberg as the host. Hydra part 7 now says what GitHub Actions does (the image build, to GHCR) and does not do (stage dispatch moved to OpenRegister flows in hydra#452), with HYDRA_FORGE as github for Conduction, forgejo only for customer instances and no default. Hydra part 6 drops the "Codeberg numbering" note and points its hydra.json example at ConductionNL/decidiq; build-an-app 4 and 8 use GitHub for petstore, the release workflow and a single docs-workflow path with the real inputs; openspec 0 and 3 point at GitHub. Big Tech part 1 keeps its story with an update note. EN + NL. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
… and name the right workflows for hydra#452 The summary's "unattended: flows" made YAML read a new mapping, so the EN build failed on the front matter. The dispatch sentence credited hydra#452 with removing hydra-build.yml and hydra-review.yml. Those went in May; #452 removed hydra-stage.yml, which #448 had added the day before. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ub-first docs(academy): the remaining tutorials are GitHub-first — Hydra CI, images, forge and example repos
… legacy The collector still described the 2026-05 move to Codeberg: Codeberg as the live source and GitHub as legacy, and each app's repo path preferred the Codeberg one. The move was reversed in 2026-07, so GitHub is where releases and new downloads happen. Swap the roles in the docstring, the section headers, the progress output and the notes field, and prefer the GitHub repo path. Codeberg release counts are still added to the total, so the StatsStrip number does not drop. The committed data/app-downloads.json fallback is updated to match. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Part 5 taught a local run through hydra-supervisor.sh, secrets/ credentials.json and logs/supervisor.log. All three are gone: the supervisor and orchestrate.sh were replaced by the hydra-dispatch and hydra-sequencer flows, and the local scripts read GH_TOKEN and CLAUDE_CODE_OAUTH_TOKEN from the environment only. Rewrite the recipe around what exists: environment credentials, a secrets/.env with the required HYDRA_FORGE=github, one stage with dev-run.sh, the whole chain with smoke-test.sh, and a real run started with a label. State that a local run writes no run record, and explain why HYDRA_LABEL_PREFIX no longer matters (the flows act on bare labels only). The quiz follows the new content. English and Dutch. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…edentials Part 2 said the supervisor daemon queued each next stage and explained a supervisor/orchestrator split that no longer exists. It now names the hydra-dispatch and hydra-sequencer flows and says the shell scripts were retired. Part 7 described secrets/credentials.json with per-persona git tokens and Claude token rotation. The flows reach the forge through one brokered source that holds only a credential id, and every run has an owner so a personal subscription only serves its owner. The credential section, the comparison table, Model 1, the troubleshooting items and quiz question 2 follow that. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ads-and-hydra-tutorials Count GitHub downloads as live; bring Hydra tutorials 2, 5 and 7 up to the flows
The parts on concept, pipelines and gates still described the retired shell pipeline: - a ready-to-build trigger - automatic hand-off from build to review to applier - an applier skip rule - a post-review quality recheck - reviews/<round>.json - *:running labels - yolo auto-merge - "22 gates" Checked against ConductionNL/hydra flows/ (identical on main and development): - Part 1: build:queued plus the change named in the issue body is the trigger. It gives the end-to-end path (build, gates, one fix pass, a PR on pass and fail, review only on code-review:queued, a human merges) and no longer promises lead times or model env vars. - Part 2: the build lane with its four outcomes, the review lane routed on hydra-verdict.json, and nothing queuing code review after a build. Also one unit of work per tick, the slot pool and lock, the labels no flow acts on, and a blocked review re-running every tick. - Part 3: about 96 declared gates and the COVERAGE line. The runner is a delegator to conduction/hydra-gates. The only re-gate is after the build's fix pass, and the false-positive example is real gate history. English and Dutch; the Dutch pages had drifted further and now say the same as the English ones. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ill tree - Part 4: skill, gate and persona counts follow the repo, or are phrased so they do not go stale (about 96 gates, 9 personas). It says what the factory actually runs. The image table now says: builder copies .claude/skills/ only; reviewer and security carry hydra-gates plus 16 hydra-gate-* skills. Wrong skill descriptions are rewritten. - Part 5: a real run starts with build:queued and the change named in the issue body. Code review is queued by hand after build:pass. The label sequence has no :running, done or merge. Image defaults are localhost/hydra:test. The base image is COPY --from, not FROM. - Part 6: the recovery ladder uses the re-queue levers that work, and says a blocked review stage must lose its :queued label first. It states that retry:queued and rebuild:queued are not handled. The supervisor-log commands and the double-prefix example are gone. The hydra.json example shows what the record flow writes. - Part 7: hydra-sequencer polls; hydra-dispatch does not. There are no dependency or sibling checks. The owner comes from the hermiq workload step; the owner:<uid> marker is dropped because nothing in hydra parses it. The quiz drops "22 gates". English and Dutch (part 7 has no Dutch page). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…-flows Hydra tutorial series: describe the pipeline the flows actually run
fix(buildiq): product page shows v0.7, matching buildiq 0.7.15
Summary
Promotes ~123 commits from
developmenttomain. Highlights:/academylinks.the-platform-momentrewrite (addressable-market segmentation) + DownloadPanel CTA polish.llms.txt,robots.txt).anonimiserenandopenwoo; removedlegacy-erp,software-catalog,woo.174 files changed · +20,243 / −1,936
Test plan
mainafter merge/solutions/anonimiserenand/solutions/openwooload; removed solution slugs 404 cleanlystatic/llms.txtandstatic/robots.txtserved at root🤖 Generated with Claude Code