Skip to content
This repository was archived by the owner on May 29, 2026. It is now read-only.

release: promote development to main (academy tutorials + ConNext pivot + partners on app/solution pages)#118

Open
WilcoLouwerse wants to merge 129 commits into
mainfrom
development
Open

release: promote development to main (academy tutorials + ConNext pivot + partners on app/solution pages)#118
WilcoLouwerse wants to merge 129 commits into
mainfrom
development

Conversation

@WilcoLouwerse

Copy link
Copy Markdown
Contributor

Summary

Promotes ~123 commits from development to main. Highlights:

  • Academy — new tutorials: spec-driven development (EN + NL), local Nextcloud, OpenSpec introductie, Hydra leerlijn, Claude Skills leerlijn, DeskDesk T5 (Integrate). Series-focus filter polish + locale-aware /academy links.
  • Blogthe-platform-moment rewrite (addressable-market segmentation) + DownloadPanel CTA polish.
  • Features — homepage hero pivot to ConNext, partners on every app & solution page, OpenRegister Showcase → MockScene, footer "Way of Work" entry, AI-crawler-friendly (llms.txt, robots.txt).
  • Solutions — added anonimiseren and openwoo; removed legacy-erp, software-catalog, woo.
  • Site — hide auto-generated "Footnotes" label, custom theme Error page, OG image refresh.
  • Copy — quality policy refreshed to January 2026; OpenTalk references removed from ConNext.
  • Chore — preset 3.20.0 bump, package-lock refresh, app download stats refresh.

174 files changed · +20,243 / −1,936

Test plan

  • Build passes on main after merge
  • Homepage hero renders with ConNext pivot
  • Academy index shows new tutorials in both EN and NL
  • App and solution pages render the partners block
  • /solutions/anonimiseren and /solutions/openwoo load; removed solution slugs 404 cleanly
  • static/llms.txt and static/robots.txt served at root

🤖 Generated with Claude Code

rubenvdlinde and others added 30 commits May 17, 2026 22:47
…rsioning + top-bar entry

OpenBuilt landed six OpenSpec changes on 2026-05-17 (wizard, versioned
model, version routing, version promotion, detail-overview, nextcloud-
nav). The marketing page hadn't been updated since the pre-spec-C era
and was advertising the v0.x "visual designer" set instead of the
shipped feature surface.

Updates:

- Hero version chip "v0.x" → "v0.3" to match the current info.xml.
- Lede now names the wizard + dev/staging/prod tiers + the auto top-bar
  entry — the three things a citizen-developer reader needs to know
  about before clicking *Install*.
- FeatureList rebuilt around the five shipped features:
  1. Wizard in drie stappen
  2. Workflows declaratief (ADR-031)
  3. Dev, staging, productie per app
  4. Eén Nextcloud, één bovenbalk (auto nav entry per published app)
  5. Virtuele app eerst, echte app als optie (Phase 2 export)

MKB-direct NL tone preserved (no em-dashes, sentence case, "je"). The
existing McpToolShelf section (from PR #51) and the "Pairs well with"
row are unchanged.
…53)

* docs(openbuilt): refresh marketing page for v0.3 — wizard + tiered versioning + top-bar entry

OpenBuilt landed six OpenSpec changes on 2026-05-17 (wizard, versioned
model, version routing, version promotion, detail-overview, nextcloud-
nav). The marketing page hadn't been updated since the pre-spec-C era
and was advertising the v0.x "visual designer" set instead of the
shipped feature surface.

Updates:

- Hero version chip "v0.x" → "v0.3" to match the current info.xml.
- Lede now names the wizard + dev/staging/prod tiers + the auto top-bar
  entry — the three things a citizen-developer reader needs to know
  about before clicking *Install*.
- FeatureList rebuilt around the five shipped features:
  1. Wizard in drie stappen
  2. Workflows declaratief (ADR-031)
  3. Dev, staging, productie per app
  4. Eén Nextcloud, één bovenbalk (auto nav entry per published app)
  5. Virtuele app eerst, echte app als optie (Phase 2 export)

MKB-direct NL tone preserved (no em-dashes, sentence case, "je"). The
existing McpToolShelf section (from PR #51) and the "Pairs well with"
row are unchanged.

* feat(openregister): retell integrations as 24 leaves in 5 categories

The 'How OpenRegister plugs into the workspace' Showcase used to list
five hand-picked integration paths (Mail/Files, Windmill/n8n, XWiki,
LLMs, Presidio) that didn't match the integrations the app ships.

Rewrite each Showcase item to describe one of the five leaf categories
from the pluggable integration registry: Core, Communication, Knowledge,
Workflow, External via OpenConnector. Each item names the leaves it
covers and links into the matching product-doc page.

Drop the separate '24 workspace leaves' Section the previous PR added
below the Showcase; the rewritten Showcase covers the same ground.
Previous Showcase used internal vocabulary ("leaves", "core/communication/
knowledge/workflow/external") and described the integration as just a
sidebar surface. Rewrite for commercial readers:

- Eyebrow: 'Integrations' (the term consumers use; 'leaves' stays in
  product docs and ADRs only).
- Title: 'Apps that truly work together.' Frame the story as turning an
  office suite into a workspace.
- Lede: name all three integration levels (sidebar tabs, dashboard
  widgets, shared service layer that lets one app call another's data).
- Item titles describe outcomes, not category names: 'Your CRM uses your
  real contacts and calendar', 'Open a ticket or lead straight from a
  Talk message', 'Project knowledge, attached to the project', 'Outside
  systems, in the same fabric'.
- Each summary leads with a concrete app-to-app use case (mail-to-
  project, lead-from-Talk, CRM-reads-Contacts) and explains the
  integration without naming the internal slot.
* feat(seo): ship AI-crawler-friendly metadata (robots.txt, llms.txt, JSON-LD, OG card)

Conduction.nl was technically crawlable (SSG, no JS-rendering risk) but
commercially invisible to AI agents: no robots.txt, no llms.txt, zero
JSON-LD, no og:image, Dutch sitemap stale. This change ships the AI-
crawling baseline so we get cited in ChatGPT/Claude/Perplexity answers
and our content gets pulled into long-term training corpora — both, on
purpose, posture documented in static/robots.txt.

Changes
- static/robots.txt — explicit allow for OAI-SearchBot, Claude-SearchBot,
  PerplexityBot, ChatGPT-User, Claude-User, GPTBot, ClaudeBot, CCBot and
  friends. Two Sitemap: lines (en + nl) for locale-suffix-blind crawlers.
- static/llms.txt — llmstxt.org-format index pointing at the 15 shipping
  apps plus company/contact tells. Dev-tool consumers (Cursor, Aider,
  MCP doc servers) read this; AI-search adoption is thin but the cost is
  near zero.
- docusaurus.config.js — wraps createConfig() return to inject
  Organization + WebSite JSON-LD via headTags[] on every page, sets
  themeConfig.image to the new OG card, and adds twitter:site /
  twitter:card / og:type baselines via themeConfig.metadata. Also adds
  sitemap options to the classic preset (changefreq, priority, ignore
  /academy/tags/** in both locales) so the sitemap is consistent across
  /sitemap.xml and /nl/sitemap.xml.
- static/img/og-conduction.png — new 1200x630 brand OG card. Cobalt
  #4376FC background, point-up hex motif per brand rules, white
  wordmark, EUPL-1.2 / ISO 27001 / Made in Amsterdam tells.

Out of scope (filed separately): SoftwareApplication JSON-LD per
/apps/<slug> page, FAQPage schema on /support, fleet rollout to the 17
per-app docs sites and to the @conduction/docusaurus-preset.

Verified: local production build emits both JSON-LD scripts in raw HTML
on / and /apps/, og:image + twitter:* meta on every page, og:type stays
'article' on blog posts (not overridden), and both sitemap.xml +
nl/sitemap.xml carry 67 URLs each with tag pages excluded.

* style(seo): drop em-dashes from robots.txt comments

Conduction writing rules ban em-dashes in published copy. robots.txt
counts as published copy (served at conduction.nl/robots.txt and read
by every AI crawler). Two em-dashes in the comment header replaced
with a colon and a period.

* feat(seo): add AI-baseline validation gate (hard-fail on regression)

CI now blocks any change that drops the AI-crawler baseline. The
validation script runs as a postbuild step so every `npm run build`
(local dev + CI) re-asserts the contract.

Checks (12, all hard-fail)
- robots.txt: exists, has Sitemap lines, allows OAI-SearchBot +
  Claude-SearchBot + PerplexityBot, has the default User-agent: *
  Allow: / block.
- llms.txt: exists, >= 1 KB (catches an accidental placeholder).
- sitemap.xml + nl/sitemap.xml: each emit >= 50 URLs.
- Homepage: >= 2 JSON-LD blocks, every block valid JSON, includes
  Organization and WebSite @type entries.
- Homepage: og:image, og:type, twitter:site, twitter:card meta tags
  present. og:image URL resolves to an actual file in the build (so
  LinkedIn / Slack / AI previews never render a 404).
- /apps/openregister: has SoftwareApplication JSON-LD with
  applicationCategory and operatingSystem populated. This is the
  regression marker for the DetailHero schema emission that ships from
  @conduction/docusaurus-preset >= 3.4.0.

Wiring
- postbuild npm script runs scripts/validate-ai-baseline.mjs.
- validate:ai-baseline npm script for ad-hoc runs.
- @conduction/docusaurus-preset bumped to ^3.4.0 so the
  SoftwareApplication check has a guaranteed source.

Adding a check: append to the CHECKS list in
scripts/validate-ai-baseline.mjs. Keep the failure message specific
so a CI annotation tells the reader exactly what regressed.

* feat(seo): consume preset 3.4.0 baseline, add per-app ledes and FAQ blocks

PR 1 shipped @conduction/docusaurus-preset 3.4.0 with AI-baseline
defaults (Organization JSON-LD, SoftwareApplication via DetailHero,
FAQPage via FAQ, postBuild robots.txt fallback, og:image, twitter
meta, sitemap options). This commit makes conduction.nl actually
consume that baseline and adds the citation-friendly content layer
on top.

Changes
- docusaurus.config.js: drop the hand-rolled headTags wrap, the
  inline Organization / WebSite JSON-LD constants, and the
  themeConfig.image / themeConfig.metadata overrides. All of it
  comes from createConfig() now. ~80 lines removed.
- src/pages/apps/*.mdx (15 files): Wikipedia-style 1-paragraph lede
  injected immediately under <DetailHero/> on every shipping app
  page. Each lede follows the template "<Name> is an open-source
  <category> app for the Nextcloud workspace. <Capabilities.>
  <Distinguishing positioning.> Released under EUPL-1.2 and
  maintained by Conduction since 2019." Sourced from each app's
  own docs site / repo, then edited for brand voice (no em-dashes,
  one claim per sentence, concrete verbs).
- src/pages/install.mdx: new 7-question FAQ block (admin install,
  Nextcloud version range, multi-app install, offline install,
  uninstall + data, missing-from-store, SLA / support).
- src/pages/iso.mdx: new 6-question FAQ block (9001 vs 27001 scope,
  self-host coverage, BIO alignment, DigiD, commonground.nu stack,
  certificate request flow).
- scripts/validate-ai-baseline.mjs: three more checks pin the
  FAQPage schema to >= 5 questions each on /support, /install, /iso.
  Hard-fail on regression. Validation now runs 15 checks total
  (was 12).

Notes
- /support already shipped a 6-question <FAQ>. Now that preset 3.4.0
  emits FAQPage JSON-LD automatically, the existing block validates
  without any source change.
- mydash README declares AGPL-3.0 while the lede template ends with
  EUPL-1.2. Filed as a follow-up to verify which is canonical; the
  lede currently says EUPL-1.2 to match brand positioning.
- softwarecatalog has two readings in its docs (IT-asset management
  vs internal user-sync). The lede goes with the conduction.nl
  positioning (IT-asset management), which matches the existing
  tagline in apps-catalog.js.

* ci: validate AI baseline on every pull request

The centralised ConductionNL/.github documentation workflow only
builds on push, schedule, and workflow_dispatch. That meant a PR
could drop robots.txt, break a sitemap, or remove SoftwareApplication
JSON-LD without the validate-ai-baseline.mjs check ever running
in CI. The defect lands; nightly cron catches it the next morning;
production is already broken.

This workflow runs npm run ci (= npm ci --legacy-peer-deps && npm
run build) on every pull_request to development or documentation.
The build's existing postbuild step runs the 15-check validator,
which exits non-zero on regression. A follow-up explicit invocation
acts as belt-and-braces in case anyone removes the postbuild hook.

GITHUB_TOKEN is passed so the prebuild app-downloads fetch stays
under the 60-req/hr unauthenticated rate limit (same pattern the
centralised workflow uses).
PR #55 bumped @conduction/docusaurus-preset to ^3.4.0 in package.json
without regenerating package-lock.json. CI uses `npm ci --legacy-peer-deps`
which is strict about lockfile sync, so every Documentation workflow
run on development since #55 merged has failed at the install step.
The AI baseline never reached production.

This commit:
- Bumps the package.json range from ^3.4.0 to ^3.5.0 (the latest
  preset published — also matches what the rest of the fleet now uses).
- Regenerates package-lock.json against the new range.
- The cooldown rule in .npmrc (min-release-age=1) blocks fresh
  @conduction/* releases by default; this regen used
  --min-release-age=0 per the .npmrc comment.

After this lands, the documentation workflow should install cleanly,
the postbuild validate-ai-baseline check should pass, and the deploy
job should publish the AI baseline (robots.txt, llms.txt, JSON-LD,
og-conduction.png, sitemaps) to www.conduction.nl for the first time.
…k override) (#57)

Companion to the AI-crawler baseline shipped in #55. Targets Google,
Bing, DuckDuckGo, and the AI surfaces those engines feed.

Title dedup (7 pages)
- about, apps, demo, partners, sidecars, solutions, support: drop the
  ", Conduction" suffix from frontmatter title:. Docusaurus appends
  " | Conduction" automatically, so the prior frontmatter produced
  "Apps, Conduction | Conduction" in browser title + og:title + SERP.
  After: "Apps | Conduction" (clean).
- index: tighten title from "Conduction, Public Tech for Nextcloud"
  to "Public Tech for Nextcloud" (still gets " | Conduction"
  appended). Trim meta description from 180 to ~157 chars so Google
  stops truncating in SERP.
- /apps/<slug> pages left as-is: "OpenRegister, Conduction" reads as
  branding (made-by signal), not a typo, so the appended duplicate
  is acceptable.

Preset 3.6.0
- Bump @conduction/docusaurus-preset to ^3.6.0 (companion preset PR
  ships sitemap lastmod, drops priority/changefreq, adds
  searchConsoleVerification opt, ships absolute www.conduction.nl
  defaults for footer legal links).
- package-lock.json regenerated with --min-release-age=0 per
  .npmrc cooldown override.

legalLinks override
- conduction-website hosts /privacy, /terms, /iso itself, so we
  override the preset's new absolute defaults back to relative
  routes. Per-app subdomain sites inherit the absolute defaults
  (they don't have /privacy etc.) so those 645 sitewide broken
  internal links get fixed automatically on their next deploy.

searchConsoleVerification scaffold
- Commented-out placeholder in docusaurus.config.js. Once ops claims
  the property in Google Search Console / Bing Webmaster Tools, the
  tokens go here and the preset emits a meta tag per token.
Preset 3.6.0 shipped with a JSDoc comment parse bug (literal */ inside
backticks closed the comment early). The fleet rollout of 3.6.0 caused
deploys to fail at config-load with 'ParseError: Missing semicolon'.

3.6.1 fixed that with a one-character edit; this commit upgrades the
lockfile so npm ci pulls 3.6.1 instead of 3.6.0. Same change rolling
across the fleet via parallel chore PRs.
…icle + IndexNow) (#61)

3.8.0 adds BreadcrumbList JSON-LD via DetailHero, TechArticle on docs pages, and IndexNow plugin.
Picks up the post-hydration stylesheet loader so canal-footer +
kade-cyclist + decorative CSS no longer block first paint.
Part of ConductionNL/.github#75 SEO epic.
chore: bump @conduction/docusaurus-preset to 3.10.0 (#79)
Initial draft of the internal Hydra learning track requested in
ConductionNL/.github#50. Six short modules (10-20 min each) that take a
reader from "what is Hydra" through a real local run to recovery
patterns, with cross-links forming a complete chain.

All six are marked draft: true + unlisted: true so they stay out of the
public build while the hosting decision (private repo / unlisted route /
besloten branch — first checkbox in #50) is still open. Each page
carries an "Intern document — niet extern delen" banner top and bottom.

Tutorial 5 covers HYDRA_LABEL_PREFIX (ConductionNL/hydra#253) in
depth — the personal-namespace knob that lets multiple devs run Hydra
against the same target repos without colliding on stage labels.
Tutorials 2 and 6 reference it where it intersects with the pipeline
and recovery flows.

Per the updated issue, the new public 1-pager at
.github/docs/hydra/README.md is linked as an optional warm-up from
tutorial 1.

Each tutorial ends with 4 Pluvo questions ready to be lifted into the
Pluvo platform later.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Convert the closing "Pluvo-vragen" sections in all six Hydra tutorials
into "Test jezelf" sections with click-to-expand Hint and Antwoord
spoilers, so the answer is hidden by default but available without
leaving the page. Adds a .tutorial-quiz card style in site.css that
overrides Docusaurus' Details theme arrow + alert variables so the
chevron sits inline with the label and the open body has readable
contrast on white.

Also tightens the "watch-list" HexCard in part 3 to state purpose
before observation, and updates Part 4 copy to match recent skill
families. package-lock churn is from dev-server runs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a public Nederlandstalige leerlijn op /academy over Claude Skills:
wat ze zijn (deel 1), je eerste skill schrijven met /skill-creator
(deel 2), en skills meten met evals (deel 3). Volgt de layout van de
interne Hydra-leerlijn (Outcomes, Prerequisites, NextSteps, Test jezelf
quizzes met Details collapsibles).

Bevat ook cross-links: Hydra deel 1 noemt de Claude Skills-leerlijn als
aanbevolen voorkennis, en Hydra deel 4 (Skills) verwijst op meerdere
plekken terug naar de nieuwe leerlijn.

Closes ConductionNL/.github#52

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Renames hydra-tutorial-4 from "skills-commands" to "skills" (with all
cross-references updated), removes the slash-command-as-separate-category
narrative from skills tutorial 1, and adds AskUserQuestion + a pointer
to the ConductionNL/.github Hydra skill-docs in skills tutorial 2.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…L7 orchestration

New deel 4 walks through learnings.md, the Capture Learnings step, the two-stage
buffer, multi-agent orchestration patterns, and the skill-level-overview dashboard
with viewing instructions. Tutorials 1-3 updated from "drie" to "vier korte modules"
and deel 3's next-step now points to deel 4.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…utorial 4

The dashboard section linked five times into ConductionNL/hydra, which is
private and returns 404 for external readers. Strip the blob URLs, drop
the defensive "Hydra is privé, dus daar krijg je een 404" workaround
quote, and reroute the "kopieer deze bestanden"-instructie via the
ContactCta + a "build it yourself" alternative.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ignored guardrail, third-person pass

- hydra-tutorial-4: "8 individuele hydra-gate-*" → 13 in container table + quiz answer (1 dispatcher + 13 gates = 14 total, matches gates-family table)
- skills tutorial 1: intro flags that deel 3 introduces the 7-level maturity-framework
- skills tutorial 2: git-status-summary guardrail forbidding --ignored on git status, so the "X not blank and not ?" staged-check doesn't also match ! lines
- skills tutorial 4 + hydra deel 4: third-person pass on narrative prose (CTA copy left alone)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Two short Dutch tutorials for conduction.nl/academy that introduce
OpenSpec to new developers and partners, per ConductionNL/.github#51:

- Part 1: "Wat is OpenSpec?" — core concepts (spec, requirement,
  scenario, change), repo layout, when to spec-first.
- Part 2: "Je eerste OpenSpec change" — /opsx-new, spec-delta with
  ADDED requirement + scenario, proposal/design/tasks, /opsx-verify.

Each part has five Pluvo questions and cross-links to the Hydra
leerlijn, the workstation tutorials, and the official OpenSpec site.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Apply the same closing-quiz treatment as the Hydra leerlijn (PR
preceding this one) to both OpenSpec tutorials: replace the static
"Pluvo-vragen" list with "Test jezelf" sections where each question
sits in a .tutorial-quiz card with click-to-expand Hint and Antwoord
spoilers (Docusaurus <Details> with summary prop).

Adds two CSS blocks to src/css/site.css that come over from the Hydra
branch:
- .tutorial-quiz styling, including overrides for Infima's
  .alert--info colours and Docusaurus' built-in Details chevron, so
  the marker flows inline and the open body has readable contrast.
- A brand-aligned blockquote treatment (cobalt palette, callout look)
  so the existing `> Naamgevingsregel` blockquote in tutorial 2 picks
  up the brand styling instead of Infima's washed-out gray default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a real /contact page on conduction.nl (previously 404 — flagged
by Google Search Console). Routes inquiries to named team members
(Remco for sales/projects, Ruben for architecture/technical, Marleen
for press/research) with email + phone + LinkedIn, plus the office
address and KvK/BTW/IBAN block.

Also wires @docusaurus/plugin-client-redirects to reclaim the SEO
equity from three legacy URLs Google still has indexed from the
pre-Docusaurus / pre-subdomain layout:
- /over-ons     -> /about/
- /openconnector -> openconnector.conduction.nl
- /openconnector/support -> openconnector.conduction.nl/support/

The other ~30 GSC 404s (componenten catalogue, WordPress placeholders,
retired training pages) have no current equivalent and are left to
fade naturally from Google's index over the next 1-3 months.
fix(seo): /contact page + redirects for legacy 404s
Adds Dutch translations for openklant, opentalk, openzaak, valtimo
sidecar pages. Preserves ZGW / NLX / Common Ground jargon natively.
Resolves duplicate-canonical warnings in Google Search Console.

Part of ConductionNL/.github#77.
…#77)

Adds Dutch translations for the sidecars overview plus keycloak, n8n,
ollama, open-webui pages. Resolves duplicate-canonical warnings in
Google Search Console caused by Docusaurus i18n falling back to EN
content when no NL file exists.

Part of ConductionNL/.github#77.
feat(i18n): NL translations for sidecars (batch 2 of 2) (#77)
feat(i18n): NL translations for sidecars (batch 1 of 2) (#77)
rubenvdlinde and others added 19 commits May 22, 2026 10:51
* academy: add spec-driven development tutorial

Companion tutorial to the new
nextcloud-vue.conduction.nl/docs/architecture/configuration-over-code
page. Teaches the schema-first, manifest-second authoring workflow
without writing any Vue, and frames the same JSON contract as the
safe sandbox for AI agents, citizen developers, and the OpenBuilt
visual editor.

Slug 'spec-driven-development' so the docs site can link to
conduction.nl/academy/spec-driven-development.

* academy: reframe spec-driven tutorial around OpenSpec

The first draft framed "spec-driven development" as the JSON-manifest
authoring workflow. That was wrong. Rewrite around OpenSpec as
practised by Hydra: humans write Markdown specs (RFC 2119 +
GIVEN/WHEN/THEN) and ADRs, an AI agent implements to them, and a
sequential quality + gatekeeping harness validates the result.

Covers: the OpenSpec directory layout (living specs vs deltas), the
org-wide vs per-app ADR tiers governing samenhang, one-feature-one-spec,
the /opsx-explore thinking stance, the /opsx-apply implementer with
ADR-031 declarative business logic, the n8n/Windmill codeless path via
WorkflowEngineInterface, and the 13 mechanical gates + team-reviewer +
team-security review harness.

* academy: prerequisites, general ADR framing, opsx phase + flow diagrams

- Prerequisites rewritten: app-design-principles + manifest/schemas as
  knowledge prereqs, an LLM tool (Claude/Mistral/Codex/other), and the
  OpenSpec skills installed from the Hydra repo.
- ADR section generalised: describes the org/app two-tier pattern
  abstractly (no link to the org set), links OpenConnector's 16 real
  per-app ADRs as the concrete application-level example.
- New "workflow, phase by phase" section using the SetupSteps component
  for the opsx phase sequence (explore → scaffold → plan → apply →
  verify → archive), plus a stacked cn-domain-tree diagram showing the
  ADR tiers feeding every phase and apply outputting manifest + schema
  with optional code/workflows.
- New "feature request to delivered functionality" section using a
  cn-pipeline for the end-to-end flow.
- MDX fix: wrap `*`-bearing literals inside <code> in JS expressions so
  the asterisks aren't parsed as emphasis.

* build: bump docusaurus-preset to ^3.20.0 for SetupSteps; disable npm cooldown

The spec-driven tutorial uses the SetupSteps component, which only
exists in @conduction/docusaurus-preset >= 3.19.0. The site was pinned
at 3.17.0, so SetupSteps imported as undefined and crashed the MDX
render at runtime (passed webpack compile, failed in the browser).

- Bump @conduction/docusaurus-preset 3.17.0 -> 3.20.0.
- Temporarily disable the .npmrc min-release-age=1 supply-chain cooldown
  so 3.20.0 (published <24h ago) installs in CI. Tracked for re-enable
  tomorrow in #115.

* fix(academy): load diagram web components browser-only to fix SSG build

The top-level `import '@conduction/docusaurus-preset/diagrams'` ran
`class CnHex extends HTMLElement` at module-eval during static site
generation, where HTMLElement is undefined — crashing SSG for every
/academy/ path (ReferenceError: HTMLElement is not defined, cascading
to "Cannot access 'assets' before initialization" on tag/author pages).

BrowserOnly defers rendering, not the import. Fix: drop the top-level
import and require() the diagrams module inside each BrowserOnly render
function, so the side-effect only runs in the browser.
Supervisor won't dispatch retry:queued or rebuild:queued while needs-input or
fail labels are still set — add the explicit cleanup command sequence (incl.
HYDRA_LABEL_PREFIX variants) to tutorial 6 and cross-reference from tutorial 2.
docs(academy): OpenSpec introductie tutorial (parts 1 + 2)
…stance

Updated the local nextcloud tutorial for better use for non technical persons
The swizzled BlogPostPage in src/theme/BlogPostPage/index.jsx wraps
MDX in .content-detail-body and bypasses the default
BlogPostItem/Content component that adds the .markdown class. The
brand blockquote CSS in src/css/site.css is scoped to
.markdown blockquote, so raw `>` callouts in the Nextcloud tutorial
fell through to Infima's washed-out grey default and rendered without
border/background.

Convert all six callouts in both the EN source and the NL translation
to `:::info`, `:::note`, `:::tip`, `:::warning`, and `:::danger`
admonitions — the same pattern used by the Hydra, Claude Skills, and
OpenSpec tutorials, which never use raw blockquotes for this reason.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The installed version of @conduction/docusaurus-preset had drifted to
3.17.0 while package.json required ^3.20.0, so the SetupStep and
SetupSteps components used by the spec-driven-development tutorial
were missing from the resolved bundle, producing dev-server runtime
errors on the academy listing page. Running npm install pulls the
preset up to 3.20.0 and adds search-insights as a transitive
dependency.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Companion NL translation for the EN canonical at
academy/2026-05-22-spec-driven-development/index.mdx, completing the
NL/EN pair so this tutorial appears on /nl/academy/ alongside the
Hydra, OpenSpec, and Claude Skills series.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…27)

The Conduction column was advertising '/academy?type=case-study' as
'Case studies', but case studies live on the Academy filter and
'Way of Work' is now the canonical 'how Conduction operates' surface
on docs.conduction.nl. Point readers at the handbook landing instead
of the academy filter.

- docusaurus.config.js: footer 'Case studies' -> 'Way of Work',
  href https://docs.conduction.nl/WayOfWork/way-of-work/.
- i18n/nl: add NL translation 'Werkwijze' for the new label.
We are no longer supporting OpenTalk as an integrated ExApp, so remove
it from the platform overview, the ExternalAppShelf, and the
app-downloads dataset. Rewrites the 'Why through the app store?'
paragraph to keep the Nextcloud Talk pitch without the OpenTalk-on-
Matrix alternative.
The "Typed data, surfaced everywhere" Showcase had a single AppMock
per tab plus an AgentTrace for the LLM tab. The first two tabs
underplayed the integration story by showing one app each in
isolation; the marketing punch is "this register data shows up
everywhere", which a multi-mock scene reads better than a single
app frame.

Mail and Files tab now composes:
  - openregister-metadata SidebarMock (md, centred)
  - nextcloud-mail and nextcloud-files WidgetMocks (sm, left edge,
    overlapping the sidebar)
  - openregister-activity WidgetMock (sm, behind the sidebar at z=0)

Windmill and n8n tab now composes:
  - openconnector-run-detail SidebarMock (md, centred)
  - openregister-activity and openconnector-runs WidgetMocks (sm,
    left edge)
  - procest-werkvoorraad WidgetMock (sm, behind the sidebar at z=0)

LLMs tab keeps the AgentTrace; the trace already reads as a mock
purpose-built for "watch the LLM working", and a scene
composition would lose that punchline.

Bumps @conduction/docusaurus-preset to ^2.6.0 (was ^2.1.0) for
WidgetMock + SidebarMock + MockScene + IntegrationIcon exports;
the components themselves landed earlier under that major.
* feat: show partners on every app and solution page

Drops a <PartnersFor> section directly below the "What it does" block
on all 16 app pages and all 5 solution pages, wired to
partners-catalog.js so /apps/<slug> and /solutions/<slug> stay in sync
with /partners from one source of truth. Replaces the hand-rolled
partner-logo strip on openwoo.

When the catalog has no partners for a subject (decidesk, doriath,
larpingapp, nldesign, openbuilt, pipelinq, procest, scholiq, shillinq,
softwarecatalog, zaakafhandelapp, anonimiseren, archief, mkb-workspace,
zaakafhandeling), the section collapses to the BecomePartner CTA only,
so every product surface keeps recruiting partners.

Site shims PartnersForApp / PartnersForSolution are a one-line MDX
drop-in that resolves the slug to the brand-cased name, runs the
matching reverse-lookup hook, and locale-keys the EN/NL copy.

Pairs with the <PartnersFor> preset component shipped in
@conduction/docusaurus-preset.

* chore(deps): bump @conduction/docusaurus-preset to ^3.18.0

Adds <PartnersFor> from the preset, required by the
PartnersForApp / PartnersForSolution shims on every app and
solution page in this branch.
…-dev

content(academy): add spec-driven-development blog post
i18n(academy): NL/EN translation pairs for Hydra, OpenSpec, Claude Skills
@MWest2020

Copy link
Copy Markdown
Member

Code Review — PR #118: release: promote development to main

Overview

Release-merge van developmentmain: 174 bestanden, +20.243 / −1.936. Bundelt ~123 commits — academy-uitbreiding (Hydra, Claude Skills, OpenSpec, DeskDesk T5/T6 series + i18n/nl mirrors), homepage-pivot naar ConNext, partners op alle app/solution pagina's, AI-crawler baseline (llms.txt/robots.txt/sitemap), solution-herstructurering, @conduction/docusaurus-preset major bump 3.3.0 → 3.20.0, Node 18 → 20, en een nieuwe PR-validation workflow. CI is groen (CodeQL pass, deploy / Build and validate pass).

Sterke punten

  • PR-gated validatie.github/workflows/validate-ai-baseline.yml draait de volledige build + AI-baseline check op iedere PR. Dat sluit precies het gat dat de inline comment beschrijft (centrale .github-workflow draait alleen op push). Belt-and-braces extra step is een nette redundantie.
  • Auditable comments — vrijwel iedere niet-triviale config-keuze (sitemap ignorePatterns, legalLinks, redirects, npmrc bypass, locale-gap voor nl) heeft een uitlegblok met waarom. Past goed bij de "boring, auditable" voorkeur.
  • Client redirects voor SEO-equity/over-ons, /openconnector*, /solutions/woo, /iso netjes afgevangen via @docusaurus/plugin-client-redirects. De keuze om de overige verwijderde URLs (componenten-catalog, legacy training) bewust te laten 404'en is gedocumenteerd.
  • Node 18 → 20 is consistent doorgevoerd: .nvmrc, package.json engines, en workflow node-version: '20'.

Aandachtspunten

1. min-release-age cooldown is uitgeschakeld (supply-chain)

.npmrc zet min-release-age=1 uit om @conduction/docusaurus-preset@3.20.0 te kunnen installeren vóór de 24h-cooldown verstreken was:

# TEMPORARILY DISABLED 2026-05-22 ... Re-enable tomorrow.
# Tracking issue: ConductionNL/conduction-website#115 (re-enable tomorrow).
# min-release-age=1
  • Vandaag is 2026-05-26 — "morgen" is 4 dagen geleden. De cooldown hoort allang weer aan te staan, óf de PR sluit met een commit die min-release-age=1 re-activeert. Niet mergen naar main met cooldown uit.
  • Bonus: de baseline stond op 1 dag, terwijl een 7-daags anti-yank-window aan te raden is. Overweeg meteen door te trekken naar min-release-age=7 bij re-enable.
  • De preset-versiesprong is groot (3.3.0 → 3.20.0, 17 minor releases). Aanbeveling: re-enable cooldown, draai daarna npm audit signatures en commit het resultaat van een verse npm ci --ignore-scripts als sanity check.

2. llms.txt is al stale bij landing

static/llms.txt beschrijft Solutions als:

"government use cases (WOO compliance, software catalog, zaakafhandeling, archief, legacy ERP migration, MKB workspace)"

…maar in dezelfde PR worden solutions/woo, solutions/legacy-erp en solutions/software-catalog verwijderd, en solutions/anonimiseren + solutions/openwoo toegevoegd. Sync de tekst (en de losse https://www.conduction.nl/iso link → die redirect nu naar /quality, dus de redirect vangt het op, maar canonical zou kloppender zijn). Een AI-crawler die llms.txt ophaalt krijgt nu een onjuiste eerste indruk van wat het bedrijf aanbiedt.

3. Redirect-dekking ontbreekt voor nl-locale

De comment in docusaurus.config.js benoemt het correct: client-redirects worden voor src/pages/*.mdx alleen voor de EN-route geëmit. Concreet: als ergens /nl/solutions/woo of /nl/iso is geïndexeerd of gedeeld (presentaties, partner-pages), gaan die naar een 404. Geen blocker — wel het overwegen waard om óf:

  • óf de NL-equivalent expliciet toe te voegen ({from: '/nl/iso', to: '/nl/quality'}),
  • óf een korte regel toe te voegen aan static/robots.txt/llms.txt over welke locale-paden gegarandeerd zijn.

4. start-script breaking change

package.json: start is docusaurus start --locale en geworden. Wie npm start gewend was om "default locale" te krijgen, krijgt nu altijd EN. start:nl is nieuw. Niet ernstig (intern team), maar wel vermelden in CHANGELOG en/of release notes — anders verliest iemand vijf minuten met "huh, NL render verschilt".

5. CI-workflow Node-versie hardcoded los van .nvmrc

.github/workflows/validate-ai-baseline.yml zet node-version: '20' letterlijk, terwijl .nvmrc ook 20 zegt. Bij een volgende bump (20 → 22) is dat twee plekken bijwerken, dus drift-risico. Triviale fix:

- name: Setup Node.js
  uses: actions/setup-node@v4
  with:
    node-version-file: '.nvmrc'

6. Voor release: dev → main PRs: graag ook GitHub release tag

Met 123 commits in één klap is git log op main straks lastig leesbaar. Overweeg een gh release create met dezelfde body als deze PR ná de merge — geeft auditors een single-page changelog.

Risico's

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

The Docusaurus dev server only serves one language at a time, which
makes the navbar language switcher look broken locally. Document the
`npm run preview` / `npm run serve` path for testing both languages on
one port.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
rubenvdlinde and others added 5 commits May 27, 2026 12:53
Mirror the structure of /quality (DetailHero + Showcase + Section + FAQ
from @conduction/docusaurus-preset). Lead with the SLA promises (uptime,
P1 response, security, capacity, maintenance, updates), then the full
SLA text. Genericized away from product-specific mentions ([product]
placeholder) and linked the OpenWoo SLA at openwoo.app/Product/SLA.

The Dutch version is the legally binding text.
…uality

Mirror DetailHero + Showcase + Section + FAQ from @conduction/docusaurus-preset.
Lead with the GDPR commitments (purpose-bound, no sharing unless necessary,
minimum retention, ISO 27001-aligned security, consent + transparency,
your GDPR rights), then the full privacy policy + DPIA + risk procedure.

The Dutch version is the legally binding text.
Replace em-dashes with appropriate punctuation (colon for labels,
parens for parentheticals, period or comma for sentence joins).
Soften a few AI-flavored phrases (capacity 'envelope' → 'allowance',
'named X by priority' → 'set X for each priority', 'no silent
repurposing/quiet bundling' → plainer prose). Pure copy edit; layout
and structure unchanged.

Same set of replacements applied to both EN and NL locales for /terms
and /privacy.
docs(readme): document multi-language local preview
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants