Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a626614
Bump node-forge from 1.3.1 to 1.3.3
dependabot[bot] Dec 5, 2025
1032fc9
Bump tar-fs
dependabot[bot] Dec 5, 2025
ef6330d
Bump on-headers and compression
dependabot[bot] Dec 5, 2025
dbe9671
Bump js-yaml from 3.14.1 to 3.14.2
dependabot[bot] Dec 5, 2025
608248a
Bump mdast-util-to-hast from 13.2.0 to 13.2.1
dependabot[bot] Dec 5, 2025
da58ea7
Merge pull request #32 from educates/dependabot/npm_and_yarn/node-for…
jorgemoralespou Dec 5, 2025
4450120
Merge pull request #31 from educates/dependabot/npm_and_yarn/multi-c3…
jorgemoralespou Dec 5, 2025
f3be6a7
Merge pull request #33 from educates/dependabot/npm_and_yarn/multi-96…
jorgemoralespou Dec 5, 2025
0a48126
Merge pull request #35 from educates/dependabot/npm_and_yarn/js-yaml-…
jorgemoralespou Dec 5, 2025
efa17a1
Merge pull request #36 from educates/dependabot/npm_and_yarn/mdast-ut…
jorgemoralespou Dec 5, 2025
2d84d91
Resolving dependabot and updatigng dependencies
jorgemoralespou Dec 5, 2025
0967068
Update action to use node 20
jorgemoralespou Dec 5, 2025
7195488
Merge branch 'main' into develop
jorgemoralespou Dec 5, 2025
9d9d868
About educates (#39)
jorgemoralespou Dec 7, 2025
6b0241d
Merge branch 'main' into develop
jorgemoralespou Dec 7, 2025
47563f9
New blog and SEO enhancements
jorgemoralespou Feb 19, 2026
429c645
Bump qs from 6.14.0 to 6.14.2 (#41)
dependabot[bot] Feb 19, 2026
03646db
Bump lodash from 4.17.21 to 4.17.23 (#42)
dependabot[bot] Feb 19, 2026
d92e7e7
Bump webpack from 5.103.0 to 5.105.2 (#43)
dependabot[bot] Feb 19, 2026
8729ba0
Fixing vulnerabilities
jorgemoralespou Feb 19, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion about-educates/deployment.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ The Educates Training Platform has some requirements for it's configuration to p

These requirements are:

- A **Kubernetes cluster**. Educates has been tested on **GKE**, **EKS** and **AKS**, **Minishift** and **Kind**.
- A **Kubernetes cluster**. Educates has been tested on **GKE**, **EKS** and **AKS**, **Talos**, **Minishift** and **Kind**.
- A **domain name** so that training portals will be accessible from the internet. In our cloud deployment we use **ExternalDNS** to create the DNS records, but you can use any other DNS provider. On local cloud deployments you can rely on external services like **nip.io** or **xip.io** or use Educates Local Resolver.
- A **wildcard certificate** for the domain name as we want access to the training portals to be secured. You can run Educates Training Platform over **http** but we don't recommend it. For local deployments, Educates CLI helps you manage your own certificates. For cloud deployments, you can use **cert-manager** to issue certificates from Let's Encrypt.
- A **policy engine**. Educates can enforce policies on the cluster and on every workshop session. It can use Kubernetes native policies or external policy engines like **Kyverno**, which is our recommended policy engine and the default one.
Expand Down
20 changes: 10 additions & 10 deletions about-educates/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,20 +16,20 @@ config:
disableMulticolor: true
---
timeline
title: "Educates History"
Dec 2019: "Educates 1.x Born"
Sept 2020: "Spring One Conference"
Apr 2021: "Tanzu Learning Center"
Feb 2022: "Educates 2.x Launch"
Nov 2023: "Broadcom Acquisition"
Aug 2024: "Educates 3.x Release"
Oct 2024: "Independent OSS Project"
Jun 2025: "Educates Hub Launch"
title Educates History
Dec 2019: Educates 1.x
Sept 2020: Spring One Conference
Apr 2021: Tanzu Learning Center
Feb 2022: Educates 2.x
Nov 2023: Broadcom Acquisition
Aug 2024: Educates 3.x Release
Oct 2024: Independent OSS Project
Jun 2025: Educates Hub Launch
```

## Key Milestones

### December 2019 - Educates 1.x is Born
### December 2019 - Educates 1.x

Educates was originally created as an internal tool for the VMware Tanzu Developer Advocates team. The team needed a platform to train users in Kubernetes and showcase developer tools and applications running on Kubernetes. This initial version laid the foundation for what would become a comprehensive training platform.

Expand Down
2 changes: 1 addition & 1 deletion about-educates/workflows.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ graph LR

### Content Development Process

1. **Content Creation**: Workshop authors write content in Markdown or AsciiDoc
1. **Content Creation**: Workshop authors write content in Markdown (using Hugo format)
2. **Local Testing**: Content is tested using the local Educates environment
3. **Image Building**: Content is packaged into an OCI container image
4. **Image Publishing**: Image is pushed to a container registry
Expand Down
55 changes: 55 additions & 0 deletions blog/2026-02-19-when-ai-content-isnt-slop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
title: "When AI content isn't slop"
slug: when-ai-content-isnt-slop
description: "The backlash against AI slop is justified, but risks dismissing purposeful content along with the noise."
authors: [graham]
tags: ["ai", "educates"]
---

In a [post on my personal site](https://grahamdumpleton.me/posts/2026/02/developer-advocacy-in-2026/) I talked about the forces reshaping developer advocacy. One theme that kept coming up was content saturation. AI has made it trivially easy to produce content, and the result is a flood of generic, shallow material that exists to fill space rather than help anyone. People have started calling this "AI slop," and the term captures something real. Recycled tutorials, SEO-bait blog posts, content that says nothing you couldn't get by asking a chatbot directly. There's a lot of it, and it's getting worse.

The backlash against AI slop is entirely justified. But I've been wondering whether it has started to go too far.

<!-- truncate -->

## The backlash is justified

To be clear, the problem is real. You can see it every time you search for something technical. The same generic "getting started" guide, rewritten by dozens of different sites (or quite possibly the same AI), each adding nothing original. Shallow tutorials that walk through the basics without any insight from someone who has actually used the technology in practice. Content that was clearly produced to fill a content calendar rather than to answer a question anyone was actually asking.

Developers have become good at spotting this. Most can tell within a few seconds whether something was written by a person with genuine experience or generated to tick a box. That's a healthy instinct. The bar for content worth reading has gone up, and honestly, that's probably a good thing. There was plenty of low-effort content being produced by humans long before AI entered the picture.

But healthy skepticism can tip over into reflexive dismissal. "AI-generated" has become a label that gets applied broadly, and once it sticks, people stop evaluating the content on its merits. The assumption becomes that if AI was involved, the content can't be worth reading. That misses some important distinctions.

## Not all AI content serves the same purpose

There are two very different ways to use AI for content. One is to mass-produce generic articles to flood search results or pad out a blog. The goal is volume, not value. Nobody designed the output with a particular audience in mind or thought carefully about what the content needed to achieve. That's slop, and the label fits.

The other is to use AI as a tool within a system you've designed, where the output has a specific structure, a specific audience, and a specific purpose. The human provides the intent and the domain knowledge. The AI helps execute within those constraints.

The problem with AI slop is not that AI generated it. The problem is that nobody designed it with care or purpose. There was no thought behind the structure, no domain expertise informing the content, no consideration for who would read it or what they'd take away from it. If you bring all of those things to the table, the output is a different thing entirely.

## Workshop instructions aren't blog posts

I've been thinking about this because of this project. [Educates](https://github.com/educates/educates-training-platform/) is an interactive training platform. It's designed for hands-on technical workshops where people learn by doing, not just by reading.

Anyone who has run a traditional workshop knows the problem. You give people a set of instructions, and half of them get stuck before they've finished the first exercise. Not because the concepts are hard, but because the mechanics are. They're copying long commands from a document, mistyping a path, missing a flag, getting an error that has nothing to do with what they're supposed to be learning. The experience becomes laborious. People switch off. They stop engaging with the material and start just trying to get through it.

Educates takes a different approach. Workshop instructions are displayed alongside live terminals and an embedded code editor. The instructions include things that learners can click on that perform actions for them. Click to run a command in the terminal. Click to open a file in the editor. Click to apply a code change. Click to run a test. The aim is to make the experience as frictionless as possible so that learners stay engaged throughout.

This creates a rhythm. You see code in context. You read an explanation of what it does and what needs to change. You click to apply the change. You click to run it and observe the result. At every step, learners are actively progressing through a guided flow rather than passively reading a wall of text. Their attention stays on the concepts being taught, not on the mechanics of following instructions. People learn more effectively because nothing about the process gives them a reason to disengage.

## Where AI fits into this

Writing good workshop content by hand is hard. Not just because of the volume of writing, but because maintaining that engaging, well-paced flow across a full workshop takes sustained focus. It's one thing to write a good explanation for one section. It's another to keep that quality consistent across dozens of sections covering an entire topic. Humans get tired. Explanations become terse halfway through. Steps that should guide the learner smoothly start to feel rushed or incomplete. The very quality that makes workshops effective, keeping learners engaged from start to finish, is the hardest thing to sustain when you're writing it all by hand.

This is where AI, with the right guidance and steering, can actually do well. When you provide the content conventions for the platform, the structure of the workshop, and clear direction about the learning flow you want, AI can generate content that maintains consistent quality and pacing throughout. It doesn't get fatigued halfway through and start cutting corners on explanations. It follows the same pattern of explaining, showing, applying, and observing as carefully in section twenty as it did in section one.

That said, this only works because the content has a defined structure, a specific format, and a clear purpose. The human still provides the design and the domain expertise. The AI operates within those constraints. With review and iteration, the result can actually be superior to what most people would produce by hand for this kind of structured content. Not because AI is inherently better at explaining things, but because maintaining that engaging flow consistently across a full workshop is something humans genuinely struggle with.

## Slop is a design problem, not a tool problem

The backlash against AI slop is well-founded. Content generated without intent, without structure, and without domain expertise behind it deserves to be dismissed. But the line should be drawn at intent and design, not at whether AI was involved in the process. Content that was designed with a clear purpose, structured for a specific use case, and reviewed by someone who understands the domain is not slop, regardless of how it was produced. Content that was generated to fill space with no particular audience in mind is slop, regardless of whether a human wrote it.

I plan to write more about what makes the interactive workshop format effective and how it changes the way people learn. For now, the point is simpler. Before dismissing AI-generated content out of hand, it's worth asking what it was designed to do and whether it does that well.

And yes, this post was itself written with the help of AI, guided by the kind of intent, experience, and hands-on steering I've been talking about. The same approach I'm applying to generating workshop content. If the argument holds, it should hold here too.
7 changes: 6 additions & 1 deletion blog/tags.yml
Original file line number Diff line number Diff line change
Expand Up @@ -86,4 +86,9 @@ resolver:
dns:
label: DNS
permalink: /dns
description: DNS
description: DNS

ai:
label: AI
permalink: /ai
description: AI
44 changes: 42 additions & 2 deletions docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,10 @@ const config: Config = {

onBrokenLinks: "throw",
onBrokenMarkdownLinks: "warn",
onBrokenAnchors: "warn",
// Set to "ignore" because navbar/footer link to homepage section anchors
// (e.g. /#use-cases, /#features) which are rendered by React components
// with id props. Docusaurus's static checker can't detect these.
onBrokenAnchors: "ignore",

markdown: {
mermaid: true,
Expand All @@ -60,6 +63,38 @@ const config: Config = {
locales: ["en"],
},

headTags: [
{
tagName: "script",
attributes: { type: "application/ld+json" },
innerHTML: JSON.stringify({
"@context": "https://schema.org",
"@type": "SoftwareApplication",
name: "Educates Training Platform",
description:
"A system for hosting interactive workshop environments in Kubernetes, or on top of a local container runtime.",
applicationCategory: "DeveloperApplication",
operatingSystem: "Kubernetes",
url: "https://educates.dev",
offers: {
"@type": "Offer",
price: "0",
priceCurrency: "USD",
},
sourceOrganization: {
"@type": "Organization",
name: "Educates",
url: "https://educates.dev",
logo: "https://educates.dev/img/educates-social-card.png",
sameAs: [
"https://github.com/educates/educates-training-platform",
"https://www.youtube.com/@EducatesTrainingPlatform",
],
},
}),
},
],

plugins: [
[
"@docusaurus/plugin-content-docs",
Expand Down Expand Up @@ -140,7 +175,12 @@ const config: Config = {

themeConfig: {
// Replace with your project's social card
image: "img/logo.svg",
image: "img/educates-social-card.png",
metadata: [
{ name: "keywords", content: "kubernetes, training, workshops, interactive learning, hands-on labs, developer education, cloud native, containers" },
{ name: "og:type", content: "website" },
{ name: "twitter:card", content: "summary_large_image" },
],
colorMode: {
defaultMode: "light",
disableSwitch: true,
Expand Down
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"@mdx-js/react": "^3.1.1",
"@mui/icons-material": "^7.1.0",
"@mui/material": "^7.1.0",
"asciinema-player": "^3.12.1",
"asciinema-player": "^3.15.0",
"clsx": "^2.1.1",
"ityped": "^1.0.3",
"prism-react-renderer": "^2.4.1",
Expand All @@ -43,6 +43,11 @@
"@types/react-dom": "^19.2.3",
"typescript": "~5.9.3"
},
"resolutions": {
"lodash-es": ">=4.17.23",
"seroval": ">=1.4.1",
"seroval-plugins": ">=1.4.1"
},
"browserslist": {
"production": [
">0.5%",
Expand Down
27 changes: 17 additions & 10 deletions src/data/featuredContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ import { FeaturedCardData } from "../components/sections/FeaturedContent";
const featuredCards: FeaturedCardData[] = [
{
image: '/img/logo.svg',
title: 'Educates is now independent',
description: 'The Educates Training Platform is is now available as an Open Source independent product. Learn more about it here.',
title: 'When AI content isn\'t slop',
description: 'The backlash against AI slop is justified, but risks dismissing purposeful content along with the noise.',
ctaLabel: 'Read blog',
ctaHref: '/blog/educates-independent',
ctaHref: '/blog/when-ai-content-isnt-slop',
},
{
image: '/img/logo.svg',
Expand All @@ -15,6 +15,13 @@ const featuredCards: FeaturedCardData[] = [
ctaLabel: 'Read blog',
ctaHref: '/blog/announcing-educates-hub',
},
{
image: '/img/logo.svg',
title: 'Educates is now independent',
description: 'The Educates Training Platform is is now available as an Open Source independent product. Learn more about it here.',
ctaLabel: 'Read blog',
ctaHref: '/blog/educates-independent',
},
// {
// image: '/img/featured-content/working_locally.jpeg',
// title: 'How to best work locally',
Expand All @@ -36,12 +43,12 @@ const featuredCards: FeaturedCardData[] = [
// ctaLabel: 'Read blog',
// ctaHref: '/blog/verify-educates-cloud-install',
// },
{
image: '/img/logo.svg',
title: 'Managing multiple versions of the Educates CLI',
description: 'Learn how to manage different versions of Educates CLI with our educatesenv tool',
ctaLabel: 'Read blog',
ctaHref: '/blog/managing-multiple-versions-of-educates-cli',
},
// {
// image: '/img/logo.svg',
// title: 'Managing multiple versions of the Educates CLI',
// description: 'Learn how to manage different versions of Educates CLI with our educatesenv tool',
// ctaLabel: 'Read blog',
// ctaHref: '/blog/managing-multiple-versions-of-educates-cli',
// },
];
export default featuredCards;
8 changes: 6 additions & 2 deletions src/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import Head from '@docusaurus/Head';
import Description from '../components/sections/Description';
import Features from '../components/sections/Features';
import UseCases from '../components/sections/UseCases';
Expand All @@ -19,8 +20,11 @@ export default function Home(): JSX.Element {

return (
<Layout
title={`${siteConfig.title}`}
description="Interactive workshop environments in Kubernetes. Educates provides a system for hosting interactive workshop environments in Kubernetes, or on top of a local container runtime.">
title="Interactive Workshop Environments on Kubernetes"
description="Educates provides a system for hosting interactive workshop environments in Kubernetes, or on top of a local container runtime. Use it for self-paced or supervised workshops and application demos.">
<Head>
<link rel="canonical" href="https://educates.dev/" />
</Head>
<Description sectionType={getSectionType(index++)} />
<UseCases sectionType={getSectionType(index++)} />
<Features sectionType={getSectionType(index++)} />
Expand Down
Binary file added static/img/educates-social-card.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions static/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
User-agent: *
Allow: /

Sitemap: https://educates.dev/sitemap.xml
Loading