59 Commits
Author SHA1 Message Date
ankn 37bff0248d Merge PR #6: restore hero portrait quality 2026-07-29 08:06:46 +02:00
ankn 25602d9826 fix(andreknie.de): restore hero portrait quality 2026-07-29 08:05:49 +02:00
ankn 76540c4455 Merge PR #5: improve accessibility and initial loading 2026-07-29 00:07:43 +02:00
ankn c4b5aa40ab fix(andreknie.de): close accessibility and performance review gaps 2026-07-29 00:05:18 +02:00
ankn 88bd952a60 feat(andreknie.de): improve accessibility and initial loading 2026-07-28 23:53:18 +02:00
ankn cf0fbd077e Merge PR #4: normalize SEO metadata and document structure
Reviewed and corrected. Verification: 47 tests passed; production build and source lint passed; all 15 routes have one title, description, canonical, main and h1; OG assets return HTTP 200.
2026-07-28 22:54:25 +02:00
ankn 4ca2c1ece8 fix(andreknie.de): close SEO review gaps 2026-07-28 22:53:37 +02:00
ankn 215aacf4a4 fix(andreknie.de): normalize SEO metadata and document structure 2026-07-28 21:42:54 +02:00
ankn b507199987 Merge PR #3: improve mobile dock and resource requests
Reviewed and corrected. Verification: 42 tests passed; production build and source lint passed; responsive browser checks passed at 375x844, 390x844, 430x932, and 1440x900.
2026-07-28 21:13:53 +02:00
ankn 0334252fed fix(andreknie.de): close package two review gaps 2026-07-28 21:13:21 +02:00
ankn 8236cce85c fix(andreknie.de): improve mobile dock and resource requests 2026-07-28 20:54:08 +02:00
ankn 71804bb2cc Merge PR #2: harden andreknie.de data lifecycle
Reviewed and verified: 35 tests, production build, source lint, credential scan, and responsive privacy-page checks passed. Includes updated Maike Mach role.
2026-07-28 20:46:22 +02:00
ankn 0459daa074 content(andreknie.de): update Maike Mach role 2026-07-28 20:42:53 +02:00
ankn 9c9b0b864d docs(andreknie.de): add remediation handoff plan 2026-07-28 11:23:30 +02:00
ankn dfae463402 fix(andreknie.de): close data lifecycle review gaps 2026-07-28 11:23:19 +02:00
ankn b31da6175a fix(andreknie.de): harden personal data lifecycle 2026-07-28 11:13:27 +02:00
ankn 772a63c622 fix(andreknie.de): keep testimonial carousel centered 2026-07-27 19:48:29 +02:00
ankn cfbd77a1a4 feat(andreknie.de): loop testimonial slider 2026-07-27 19:31:48 +02:00
ankn b8c6079e3a ci(andreknie.de): recreate Caddy container for config changes 2026-07-27 17:14:05 +02:00
ankn a6e6dcf1a2 ci(andreknie.de): force Caddy config refresh 2026-07-27 17:09:51 +02:00
ankn 2973c1ebee ci(andreknie.de): reload Caddy after deploy 2026-07-27 17:04:54 +02:00
ankn 9defbf96c7 chore(andreknie.de): preserve deploy script executable bit 2026-07-27 16:53:23 +02:00
ankn cf14b38501 chore(andreknie.de): sync spoke updates 2026-07-27 16:51:30 +02:00
ankn 27bf001b9d fix(andreknie.de): configure Umami tracking 2026-07-27 16:46:53 +02:00
ankn 6b34632d3e docs: finalize security audit, perform final npm audit fix, greenlight for launch 2026-07-26 15:36:00 +02:00
ankn 3b8ab885d6 feat(ui): redesign testimonial slider to manual snap carousel with equal card heights 2026-07-26 15:18:31 +02:00
ankn dc8b7bdcc0 chore: add patch script to public directory for easy VPS fixing 2026-07-26 13:07:57 +02:00
ankn 806646dec9 chore: remove temporary note graph patch from deploy workflow 2026-07-26 13:04:11 +02:00
ankn a028ce7f03 chore: temporary patch to update limits via active CV deploy pipeline 2026-07-26 10:49:00 +02:00
ankn 09a83f4f95 fix: restore germany-outline to PNG to fix canvas transparency parsing 2026-07-26 10:46:05 +02:00
ankn 7d1cfdc44e chore: temporary workflow to patch server RAM limits 2026-07-26 10:42:21 +02:00
ankn 21c05864af perf: strictly limit memory usage for notegraph and orgmylife 2026-07-26 10:35:53 +02:00
ankn 789a200595 perf: optimize homepage and logo images to webp 2026-07-26 10:18:43 +02:00
ankn fabc63edf5 perf: optimize kniepunkt images to webp, add lazy loading and thumbnails 2026-07-26 10:12:58 +02:00
ankn b4cff9f396 fix: ensure dist folder is explicitly copied to VM 2026-07-26 08:50:14 +02:00
ankn c1803504c6 perf: strictly limit memory usage for umami and backend 2026-07-26 08:33:50 +02:00
ankn c2a9bb51fa fix: remove external port bindings for umami and backend 2026-07-26 08:30:51 +02:00
ankn 2e83750cb7 feat: group private apps into andreknie-privat 2026-07-25 15:47:01 +02:00
ankn 4c7d48ae6d feat: restructure dHive knowledge into OKF layout 2026-07-25 15:18:58 +02:00
ankn 2ad85ddf86 feat: prepare federated Gitea actions workflow 2026-07-25 15:06:54 +02:00
ankn 53dd82707c ci: add workflow_dispatch and trigger real deploy
Deploy CV Site (andreknie.de) / deploy (push) Canceled after 0s
2026-07-25 12:14:45 +02:00
ankn a9e49a67b2 ci: trigger andreknie.de deployment workflow 2026-07-25 12:07:07 +02:00
ankn 5012ccd607 ci: hardcode SMTP host and port 2026-07-25 11:43:24 +02:00
ankn fbcd7a506e ci: unify SSH and SMTP secrets 2026-07-22 15:52:41 +02:00
ankn 09321872fb ci: disable NoteGraph deployment workflow 2026-07-22 15:49:17 +02:00
ankn b46de6dc7d ci: migrate GitHub actions to Gitea actions
Deploy CV Site (andreknie.de) / deploy (push) Canceled after 0s
2026-07-22 15:42:06 +02:00
ankn e1cf49b0a2 build(deps): update 4 npm packages 2026-07-22 15:27:55 +02:00
ankn 1ab41bf3ec feat(deploy): add umami tracking, fix CSP, and lock JSON writes 2026-07-22 15:23:28 +02:00
ankn f3cfacfd11 Merge pull request 'feat: migrate agents to monorepo and update federation configs' (#1) from feat/federation-setup into master 2026-07-17 22:44:12 +02:00
ankn 8db07e5d21 feat: migrate agents to monorepo and update federation configs 2026-07-17 21:15:33 +02:00
ankn 38a9a11772 chore: add GitLab CI deployment for andreknie.de 2026-07-13 21:32:22 +02:00
ankn 042d83f6d6 chore: remove OrgMyLife github workflows 2026-07-13 21:31:22 +02:00
ankn 6d063caada chore: migrate OrgMyLife to GitLab CI and optimize scheduled jobs 2026-07-13 21:31:12 +02:00
ankn 043efc0dd3 chore: initialize git-crypt contexts and encrypt secrets 2026-07-13 21:28:48 +02:00
ankn 429e3d9785 docs: add todo to optimize runner compute efficiency 2026-07-13 00:13:47 +02:00
ankn ad6ba2199a docs: add GitLab migration plan and document disabled GitHub Actions 2026-07-13 00:11:35 +02:00
ankn 59e501cda8 docs(steering): add ownership rules — external repos are read-only, no code changes or MRs 2026-07-10 18:49:58 +02:00
ankn 18f6e2732e test: add test suites for Projekt-KIQ-HP (12 tests) and andreknie.de validation (16 tests)
- Projekt-KIQ-HP: vitest + server API tests (health, login, auth, access-requests)
- andreknie.de: validation utility tests (email, contact, talk-request, newsletter, resource-download)
- db-planet-mcp-server: existing 7 tests confirmed working
2026-07-10 18:43:41 +02:00
ankn 6ae0c91539 fix(ai-orchestrator): correct test expectation for sanitize_workspace_key (hyphen is allowed) 2026-07-10 18:31:15 +02:00
935 changed files with 132463 additions and 3724 deletions
+24
View File
@@ -0,0 +1,24 @@
# Agent Rules
## Model Selection Advisor
Whenever you receive a new user request or begin a new task, you MUST invoke the `model_advisor` skill to evaluate the optimal model and tool strategy before proceeding with any significant planning or code modifications.
## OKF Knowledge Base Access
Whenever the user asks you to search, query, access, or update their "knowledge", "OKF", or "Wissensdatenbank", you MUST use the custom `ctx-guard` CLI tool.
The tool is executed from the Orchestrator's virtual environment: `/home/andre/coden/Orchestrator/.venv/bin/ctx-guard knowledge`.
**Available commands:**
- `search`: e.g., `/home/andre/coden/Orchestrator/.venv/bin/ctx-guard knowledge search "query" --limit 5`
- `capture`: e.g., `/home/andre/coden/Orchestrator/.venv/bin/ctx-guard knowledge capture "Note" --context privat`
- `status`: e.g., `/home/andre/coden/Orchestrator/.venv/bin/ctx-guard knowledge status`
- `ingest`: e.g., `/home/andre/coden/Orchestrator/.venv/bin/ctx-guard knowledge ingest`
Always run this command directly using your `run_command` tool to retrieve or update knowledge before answering the user's queries.
## PR Workflow Rule
All code changes or configurations made by agents MUST go through a Pull Request / Merge Request.
- You are not allowed to do quicksaves directly to the main branch.
- You must create a new branch, commit your changes, push to the remote, and open a PR.
- After creating the PR, you must review it for viability and only merge it once confirmed.
+11
View File
@@ -0,0 +1,11 @@
{
"last_updated": "2026-07-16T20:12:30Z",
"providers": {
"codex": {
"models": []
},
"antigravity": {
"models": []
}
}
}
+22
View File
@@ -0,0 +1,22 @@
#!/bin/bash
# check_quotas.sh - Modular script to check quotas
export PATH="$HOME/.local/bin:$PATH"
check_codex_quota() {
if command -v codex &> /dev/null; then
echo "[Codex Quota]"
codex quota || echo "Failed to fetch Codex quota"
fi
}
check_agy_quota() {
if command -v agy &> /dev/null; then
echo "[Antigravity Quota]"
agy quota || echo "Failed to fetch Antigravity quota"
fi
}
echo "--- Current Quotas ---"
check_codex_quota
check_agy_quota
echo "----------------------"
+23
View File
@@ -0,0 +1,23 @@
#!/bin/bash
# install_clis.sh - Install configured CLIs
set -e
echo "Starting CLI installations..."
echo "Checking codex..."
if command -v codex &> /dev/null; then
echo "codex is already installed. Version: $(codex --version 2>/dev/null || echo 'unknown')"
else
echo "Installing codex via curl..."
curl -fsSL https://chatgpt.com/codex/install.sh | sh
echo "codex installed successfully."
fi
echo "Checking agy (antigravity)..."
if command -v agy &> /dev/null; then
echo "agy is already installed."
else
echo "Warning: agy is not installed. Please install it manually."
fi
echo "All CLIs are set up."
+23
View File
@@ -0,0 +1,23 @@
#!/bin/bash
# setup_apis.sh - Trigger browser login flows
set -e
export PATH="$HOME/.local/bin:$PATH"
CLIS=("codex" "agy")
echo "Starting API Configuration via Browser Login..."
for cli in "${CLIS[@]}"; do
echo "Configuring $cli..."
if command -v "$cli" &> /dev/null; then
if [ "$cli" == "agy" ]; then
"$cli" auth
else
"$cli" login
fi
echo "$cli configured."
else
echo "Warning: $cli not installed. Please run install_clis.sh first."
fi
done
echo "API setup complete."
+35
View File
@@ -0,0 +1,35 @@
#!/bin/bash
# update_models_config.sh - Fetches latest models and quotas
export PATH="$HOME/.local/bin:$PATH"
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CONFIG_FILE="$DIR/../models_config.json"
echo "{" > "$CONFIG_FILE"
echo " \"last_updated\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"," >> "$CONFIG_FILE"
# Logic to update config
echo " \"providers\": {" >> "$CONFIG_FILE"
# Codex Models
echo " \"codex\": {" >> "$CONFIG_FILE"
if command -v codex &> /dev/null; then
echo " \"models\": $(codex models --json 2>/dev/null || echo '[]')" >> "$CONFIG_FILE"
else
echo " \"models\": []" >> "$CONFIG_FILE"
fi
echo " }," >> "$CONFIG_FILE"
# Antigravity Models
echo " \"antigravity\": {" >> "$CONFIG_FILE"
if command -v agy &> /dev/null; then
echo " \"models\": $(agy models --json 2>/dev/null || echo '[]')" >> "$CONFIG_FILE"
else
echo " \"models\": []" >> "$CONFIG_FILE"
fi
echo " }" >> "$CONFIG_FILE"
echo " }" >> "$CONFIG_FILE"
echo "}" >> "$CONFIG_FILE"
echo "Models config updated at $CONFIG_FILE"
+35
View File
@@ -0,0 +1,35 @@
---
name: model_advisor
description: Evaluates a task and orchestrates execution across available CLI models based on cost, quotas, and strengths.
---
# Instructions
You have been invoked to act as a central orchestrator. You must evaluate the task, check available models and quotas, and delegate the work via CLI.
## Step 1: Check Quotas & Models
Run the following scripts from your workspace:
- `.agents/scripts/check_quotas.sh`
- Review `.agents/models_config.json` to see currently available models.
## Step 2: Evaluate the Task
Consider the following criteria:
1. **Complexity & Context**: Does it require massive context (Gemini Pro) or deep nuance (Claude Sonnet)?
2. **Cost & Quota**: Are quotas low? Use cheaper models if the task is simple.
## Step 3: Output a Recommendation & Delegate
If the task is best suited for a CLI-driven model (e.g., Codex or Antigravity with a specific model), you MUST proactively write and execute the terminal command to delegate the task.
Example output:
> [!TIP]
> **Model Advisor Recommendation**: The quota for Antigravity is healthy. I am delegating this refactoring task to Claude 3.5 Sonnet via the CLI.
Example command you might run:
```bash
agy run --model claude-3-5-sonnet "refactor the payment gateway"
```
If the task is best suited for the *current* IDE model, advise the user to proceed normally without CLI delegation. If it's suited for an IDE model you are *not* currently using, advise the user to switch models manually in the IDE.
## Step 4: Proceed
Once the CLI command completes, or if you decided to handle it locally, complete the user's request.
@@ -3,6 +3,8 @@ name: Deploy to VPS
on:
push:
branches: [main]
paths:
- 'shared/AI-Orchestrator/**'
jobs:
deploy:
@@ -3,6 +3,8 @@ name: Deploy Jury Voting
on:
push:
branches:
paths:
- 'dhive/Jury-Voting/**'
- main
workflow_dispatch:
@@ -3,6 +3,8 @@ name: CI and Deploy
on:
push:
branches:
paths:
- 'dhive/Projekt-KIQ-HP/**'
- main
workflow_dispatch:
@@ -79,10 +81,10 @@ jobs:
'ADMIN_USER=${{ secrets.KIQ_ADMIN_USER }}' \
'ADMIN_PASSWORD=${{ secrets.KIQ_ADMIN_PASSWORD }}' \
'SESSION_SECRET=${{ secrets.KIQ_SESSION_SECRET }}' \
'SMTP_HOST=${{ secrets.KIQ_SMTP_HOST }}' \
'SMTP_PORT=${{ secrets.KIQ_SMTP_PORT }}' \
'SMTP_USER=${{ secrets.KIQ_SMTP_USER }}' \
'SMTP_PASS=${{ secrets.KIQ_SMTP_PASS }}' \
'SMTP_HOST=smtp.ionos.de' \
'SMTP_PORT=587' \
'SMTP_USER=${{ secrets.SMTP_USER }}' \
'SMTP_PASS=${{ secrets.SMTP_PASS }}' \
'ALERT_EMAIL=${{ secrets.KIQ_ALERT_EMAIL }}' \
> ${DEPLOY_PATH}/.env"
+3
View File
@@ -106,3 +106,6 @@ All filenames must be OneDrive-safe:
- No single quotes or backticks
- Replace umlauts in filenames: ä→ae, ö→oe, ü→ue, ß→ss
- Use hyphens instead of special characters
## Agent Restrictions
- ONLY the human user is allowed to use `sudo`. Agents MUST NOT attempt to use `sudo` or request `sudo` access.
+17
View File
@@ -28,11 +28,28 @@ On this machine, PowerShell is the shell. Use `;` to chain commands, NOT `&&` (w
## Key Decisions
- **Bahn repos stay untouched** as independent remotes. The monorepo organizes them but doesn't own them.
- **External repos are READ-ONLY in the monorepo.** Never modify code, add tests, or create MRs for: aisupport, Confluence_Bot, O2C-Harness, db-planet-mcp-server, wissensdatenbank. Only COMPONENT.md (monorepo wrapper metadata) is allowed.
- **Jury-Voting** is dhive (not privat). Will be transferred to dhive GitLab later.
- **NoteGraph** needs a complete redo — superseded by the monorepo knowledge store.
- **symphony** is a read-only reference (pinned).
- Secrets go in `.secrets` (gitignored) or encrypted via git-crypt per context.
## Ownership Rules
| Repo | Owner | Editable? |
|------|-------|-----------|
| bahn/aisupport | DB GitLab (Team) | ❌ read-only |
| bahn/Analyse-O2C-C2S | Andre (DB GitLab) | ✅ |
| bahn/awesome-bahn-mcp-servers | monorepo-internal | ✅ |
| bahn/Confluence_Bot | DB GitLab (Team) | ❌ read-only |
| bahn/db-planet-mcp-server | DB GitLab (Team) | ❌ read-only |
| bahn/O2C-Harness | DB GitLab (Team) | ❌ read-only |
| bahn/project-audit | Andre (DB GitLab) | ✅ |
| bahn/wissensdatenbank | DB GitLab (Team) | ❌ read-only (subtree) |
| dhive/* | Andre (GitHub) | ✅ |
| privat/* | Andre (GitHub) | ✅ |
| shared/* | Andre (GitHub/internal) | ✅ |
## Python Environment
The monorepo CLI tool is at `shared/tools/monorepo-cli/`. Tests run with:
+1
View File
@@ -0,0 +1 @@
{}
+1
View File
@@ -0,0 +1 @@
{}
+33
View File
@@ -0,0 +1,33 @@
{
"file-explorer": true,
"global-search": true,
"switcher": true,
"graph": true,
"backlink": true,
"canvas": true,
"outgoing-link": true,
"tag-pane": true,
"footnotes": false,
"properties": true,
"page-preview": true,
"daily-notes": true,
"templates": true,
"note-composer": true,
"command-palette": true,
"slash-command": false,
"editor-status": true,
"bookmarks": true,
"markdown-importer": false,
"zk-prefixer": false,
"random-note": false,
"outline": true,
"word-count": true,
"slides": false,
"audio-recorder": false,
"workspaces": false,
"file-recovery": true,
"publish": false,
"sync": true,
"bases": true,
"webviewer": false
}
+37
View File
@@ -0,0 +1,37 @@
{
"collapse-filter": false,
"search": "",
"showTags": false,
"showAttachments": false,
"hideUnresolved": false,
"showOrphans": false,
"collapse-color-groups": false,
"colorGroups": [
{
"query": "bahn",
"color": {
"a": 1,
"rgb": 14701138
}
},
{
"query": "README",
"color": {
"a": 1,
"rgb": 14725458
}
}
],
"collapse-display": true,
"showArrow": false,
"textFadeMultiplier": 0,
"nodeSizeMultiplier": 1,
"lineSizeMultiplier": 1,
"collapse-forces": true,
"centerStrength": 0.518713248970312,
"repelStrength": 10,
"linkStrength": 1,
"linkDistance": 250,
"scale": 0.3278612817696069,
"close": true
}
+202
View File
@@ -0,0 +1,202 @@
{
"main": {
"id": "65ff358f856d0b1a",
"type": "split",
"children": [
{
"id": "2914df35e084ed27",
"type": "tabs",
"children": [
{
"id": "b8ba1520bc8176ed",
"type": "leaf",
"state": {
"type": "empty",
"state": {},
"icon": "lucide-file",
"title": "New tab"
}
}
]
}
],
"direction": "vertical"
},
"left": {
"id": "cd0c55edd9200b50",
"type": "split",
"children": [
{
"id": "3857f784ea660c88",
"type": "tabs",
"children": [
{
"id": "dc73d749370c354d",
"type": "leaf",
"state": {
"type": "file-explorer",
"state": {
"sortOrder": "alphabetical",
"autoReveal": false
},
"icon": "lucide-folder-closed",
"title": "Files"
}
},
{
"id": "e4a5c52ec96231c0",
"type": "leaf",
"state": {
"type": "search",
"state": {
"query": "news 18. Juli",
"matchingCase": false,
"explainSearch": false,
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical"
},
"icon": "lucide-search",
"title": "Search"
}
},
{
"id": "4f2016fa722f537e",
"type": "leaf",
"state": {
"type": "bookmarks",
"state": {},
"icon": "lucide-bookmark",
"title": "Bookmarks"
}
}
],
"currentTab": 1
}
],
"direction": "horizontal",
"width": 300
},
"right": {
"id": "031a0f093737e6bd",
"type": "split",
"children": [
{
"id": "1b73b08cb7e18c6a",
"type": "tabs",
"children": [
{
"id": "73f7f3b46877b489",
"type": "leaf",
"state": {
"type": "backlink",
"state": {
"collapseAll": false,
"extraContext": false,
"sortOrder": "alphabetical",
"showSearch": false,
"searchQuery": "",
"backlinkCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-coming-in",
"title": "Backlinks"
}
},
{
"id": "2ed2bd936ddd2394",
"type": "leaf",
"state": {
"type": "outgoing-link",
"state": {
"linksCollapsed": false,
"unlinkedCollapsed": true
},
"icon": "links-going-out",
"title": "Outgoing links"
}
},
{
"id": "c09fd789ce68a794",
"type": "leaf",
"state": {
"type": "tag",
"state": {
"sortOrder": "frequency",
"useHierarchy": true,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-tags",
"title": "Tags"
}
},
{
"id": "3bb0dae47b1f969c",
"type": "leaf",
"state": {
"type": "all-properties",
"state": {
"sortOrder": "frequency",
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-archive",
"title": "All properties"
}
},
{
"id": "2dfbe77fe9b40187",
"type": "leaf",
"state": {
"type": "outline",
"state": {
"followCursor": false,
"showSearch": false,
"searchQuery": ""
},
"icon": "lucide-list",
"title": "Outline"
}
}
]
}
],
"direction": "horizontal",
"width": 300
},
"left-ribbon": {
"hiddenItems": {
"graph:Open graph view": false,
"switcher:Open quick switcher": false,
"canvas:Create new canvas": false,
"daily-notes:Open today's daily note": false,
"templates:Insert template": false,
"command-palette:Open command palette": false,
"bases:Create new base": false
}
},
"active": "b8ba1520bc8176ed",
"lastOpenFiles": [
"privat/CV/output/andreknie.de/SPEC.md",
"bahn/wissensdatenbank/output/processed/allgemein/web/technische-fachthemen.md",
"privat/CV/andreknie.de/content/kniepunkt/009-post-kniepunkt-009-ki-prophezeiung.md",
"privat/CV/andreknie.de/content/kniepunkt/008-post-kniepunkt-008-der-spiegeltest.md",
"privat/CV/andreknie.de/content/kniepunkt/007-post-kniepunkt-007-europas-ki-polyamorie.md",
"privat/CV/andreknie.de/content/kniepunkt/005-post-kniepunkt-005-konflikte-im-ki-olymp.md",
"privat/CV/andreknie.de/content/kniepunkt/003-post-kniepunkt-003-ki-als-pferderennen.md",
"privat/CV/andreknie.de/content/kniepunkt/001-post-kniepunkt-001-die-biblische-ki.md",
"privat/CV/andreknie.de/content/posts/2025-07-18-warum-sich-der-einsatz-von-ki-in-sozialen-und-kulturellen-bereichen-lohnt.md",
"privat/CV/andreknie.de/content/posts/2025-06-22-noch-ein-knapper-monat-bis-zur-enthuellung-der-ergebnisse-die-teams-waren-und-si.md",
"bahn/project-audit/data/confluence-export/pages/503104237_2025-10-24 Handlungsoptionen Releasevorgehen und passende QA.md",
"privat/CV/andreknie.de/content/posts/2025-11-21-eigentlich-muesste-ich-heute-etwas-ueber-den-omnibus-und-die-drohende-erosion-de.md",
"docs/COMPONENT-STATUS-2026-07.md",
"docs/MONOREPO-HEALTH-CHECKLIST.md",
"docs/monorepo-presentation.md",
"docs/monorepo-summary.md",
"docs/quickstart.md",
"README.md",
"SETUP_DEVICE.md",
"privat/CV/andreknie.de/node_modules/ms/license.md"
]
}
+76
View File
@@ -0,0 +1,76 @@
# New Device Setup Guide
This guide explains how to get your full Monorepo, AI Orchestrator, CLI agents, and Knowledge Base (`ctx-guard`) up and running on a brand new device.
## Prerequisites
Ensure the following tools are installed on your new device:
- `git`
- `python3.12` or newer
- `pipx`
- `curl`
## Step 1: Clone the Monorepo
Clone the Orchestrator to your preferred workspace directory (e.g., `~/coden`):
```bash
mkdir -p ~/coden
cd ~/coden
git clone https://git.d-hive.de/ankn/Orchestrator.git
cd Orchestrator
```
## Step 2: Set up the Knowledge CLI (`ctx-guard`)
The `ctx-guard` tool requires a Python virtual environment.
```bash
cd ~/coden/Orchestrator
python3 -m venv .venv
source .venv/bin/activate
# Install the monorepo-cli package in editable mode
cd shared/tools/monorepo-cli
pip install -e .
```
To register the new machine to your federation topology, run the built-in onboard command:
```bash
# Replace <machine_name> with your device name
ctx-guard onboard <machine_name> "privat,dhive,bahn,shared"
```
## Step 3: Install the AI CLIs
Install the Codex CLI:
```bash
curl -fsSL https://chatgpt.com/codex/install.sh | sh
```
Install the Antigravity CLI:
```bash
curl -fsSL https://antigravity.google/cli/install.sh | bash
```
Run `codex login` and `agy login` in your terminal to authenticate via the browser.
## Step 4: AI Agent Customizations
Because the `.agents` folder is now version-controlled inside the Orchestrator monorepo (`~/coden/Orchestrator/.agents`), your AI agents will *automatically* discover your custom skills (like `model_advisor`) and rules (like strictly using `ctx-guard` for knowledge tasks).
To ensure your models catalog is kept up to date, you can manually run the updater script:
```bash
cd ~/coden/Orchestrator
./.agents/scripts/update_models_config.sh
```
*(Note: In your primary environment, an agent has scheduled this as a daily cron job. You can instruct the agent to set up the same schedule on the new device by typing `/schedule daily run .agents/scripts/update_models_config.sh` in the chat).*
## Step 5: Sync Federation Repositories
Finally, pull down the rest of your private and shared federation repositories from the `dhive` GitLab:
```bash
ctx-guard fed-sync --context dhive
```
Your environment is now fully identical to your original machine!
Binary file not shown.
+1141 -1
View File
File diff suppressed because it is too large Load Diff
+6 -1
View File
@@ -8,6 +8,7 @@
"build": "vite build",
"lint": "eslint .",
"preview": "vite preview",
"test": "vitest run",
"start:server": "node server/index.js"
},
"dependencies": {
@@ -22,6 +23,8 @@
},
"devDependencies": {
"@eslint/js": "^10.0.1",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@types/react": "^19.2.14",
"@types/react-dom": "^19.2.3",
"@vitejs/plugin-react": "^6.0.1",
@@ -29,6 +32,8 @@
"eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.5.2",
"globals": "^17.4.0",
"vite": "^8.0.4"
"jsdom": "^29.1.1",
"vite": "^8.0.4",
"vitest": "^4.1.10"
}
}
@@ -0,0 +1,270 @@
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';
import express from 'express';
import cors from 'cors';
import cookieParser from 'cookie-parser';
import crypto from 'crypto';
import { mkdirSync, writeFileSync, readFileSync, existsSync, rmSync } from 'fs';
import { join, dirname } from 'path';
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const TEST_DATA_DIR = join(__dirname, '..', 'data-test');
const TEST_DATA_FILE = join(TEST_DATA_DIR, 'access-requests.json');
function createTestApp() {
mkdirSync(TEST_DATA_DIR, { recursive: true });
writeFileSync(TEST_DATA_FILE, '[]', 'utf-8');
const sessions = new Map();
const ADMIN_USER = 'admin';
const ADMIN_PASSWORD = 'testpass';
const app = express();
app.use(cors());
app.use(express.json());
app.use(cookieParser('test-secret'));
function createSession(user) {
const token = crypto.randomBytes(32).toString('hex');
sessions.set(token, { user, createdAt: Date.now() });
return token;
}
function getSession(token) {
return sessions.get(token) || null;
}
function requireAuth(req, res, next) {
const token = req.cookies?.kiq_session;
if (!token) return res.status(401).json({ error: 'Nicht authentifiziert' });
const session = getSession(token);
if (!session) return res.status(401).json({ error: 'Sitzung abgelaufen' });
req.user = session.user;
next();
}
app.get('/api/health', (_req, res) => {
res.json({ status: 'ok', time: new Date().toISOString() });
});
app.post('/api/login', (req, res) => {
const { username, password } = req.body;
if (username === ADMIN_USER && password === ADMIN_PASSWORD) {
const token = createSession({ username, role: 'admin' });
res.cookie('kiq_session', token, { httpOnly: true, sameSite: 'strict' });
return res.json({ user: { username, role: 'admin' } });
}
return res.status(401).json({ error: 'Ungültige Anmeldedaten' });
});
app.post('/api/logout', (req, res) => {
const token = req.cookies?.kiq_session;
if (token) sessions.delete(token);
res.clearCookie('kiq_session');
res.json({ ok: true });
});
app.get('/api/me', (req, res) => {
const token = req.cookies?.kiq_session;
if (!token) return res.json({ user: null });
const session = getSession(token);
if (!session) return res.json({ user: null });
res.json({ user: session.user });
});
app.post('/api/access-requests', (req, res) => {
const { user_data } = req.body;
if (!user_data || !user_data.name || !user_data.email || !user_data.company) {
return res.status(400).json({ error: 'Pflichtfelder fehlen' });
}
const requests = JSON.parse(readFileSync(TEST_DATA_FILE, 'utf-8'));
const newRequest = {
id: crypto.randomUUID(),
user_data,
status: 'pending',
created_at: new Date().toISOString(),
};
requests.push(newRequest);
writeFileSync(TEST_DATA_FILE, JSON.stringify(requests, null, 2), 'utf-8');
res.status(201).json({ ok: true, id: newRequest.id });
});
app.get('/api/access-requests', requireAuth, (_req, res) => {
const requests = JSON.parse(readFileSync(TEST_DATA_FILE, 'utf-8'));
requests.sort((a, b) => new Date(b.created_at) - new Date(a.created_at));
res.json(requests);
});
app.put('/api/access-requests/:id', requireAuth, (req, res) => {
const { id } = req.params;
const { status } = req.body;
if (!['pending', 'approved', 'rejected'].includes(status)) {
return res.status(400).json({ error: 'Ungültiger Status' });
}
const requests = JSON.parse(readFileSync(TEST_DATA_FILE, 'utf-8'));
const idx = requests.findIndex(r => r.id === id);
if (idx === -1) return res.status(404).json({ error: 'Anfrage nicht gefunden' });
requests[idx].status = status;
writeFileSync(TEST_DATA_FILE, JSON.stringify(requests, null, 2), 'utf-8');
res.json({ ok: true });
});
return app;
}
// --- Test Setup ---
let server;
let baseUrl;
beforeAll(async () => {
const app = createTestApp();
await new Promise((resolve) => {
server = app.listen(0, () => {
const addr = server.address();
baseUrl = `http://localhost:${addr.port}`;
resolve();
});
});
});
afterAll(() => {
if (server) server.close();
if (existsSync(TEST_DATA_DIR)) rmSync(TEST_DATA_DIR, { recursive: true, force: true });
});
beforeEach(() => {
writeFileSync(TEST_DATA_FILE, '[]', 'utf-8');
});
// --- Tests ---
describe('KIQ Server API', () => {
describe('GET /api/health', () => {
it('returns ok status', async () => {
const res = await fetch(`${baseUrl}/api/health`);
expect(res.status).toBe(200);
const data = await res.json();
expect(data.status).toBe('ok');
expect(data.time).toBeTruthy();
});
});
describe('POST /api/login', () => {
it('accepts valid credentials', async () => {
const res = await fetch(`${baseUrl}/api/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: 'testpass' }),
});
expect(res.status).toBe(200);
const data = await res.json();
expect(data.user.username).toBe('admin');
expect(data.user.role).toBe('admin');
});
it('rejects invalid credentials', async () => {
const res = await fetch(`${baseUrl}/api/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: 'wrong' }),
});
expect(res.status).toBe(401);
});
it('sets session cookie on success', async () => {
const res = await fetch(`${baseUrl}/api/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ username: 'admin', password: 'testpass' }),
});
const setCookie = res.headers.get('set-cookie');
expect(setCookie).toContain('kiq_session');
});
});
describe('GET /api/me', () => {
it('returns null user without session', async () => {
const res = await fetch(`${baseUrl}/api/me`);
expect(res.status).toBe(200);
const data = await res.json();
expect(data.user).toBeNull();
});
});
describe('POST /api/access-requests', () => {
it('creates a new access request', async () => {
const res = await fetch(`${baseUrl}/api/access-requests`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
user_data: {
name: 'Max Mustermann',
email: 'max@example.com',
company: 'Test GmbH',
role: 'Developer',
purpose: 'Testing',
},
}),
});
expect(res.status).toBe(201);
const data = await res.json();
expect(data.ok).toBe(true);
expect(data.id).toBeTruthy();
});
it('rejects when name is missing', async () => {
const res = await fetch(`${baseUrl}/api/access-requests`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_data: { email: 'x@x.com', company: 'X' } }),
});
expect(res.status).toBe(400);
});
it('rejects when email is missing', async () => {
const res = await fetch(`${baseUrl}/api/access-requests`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_data: { name: 'Max', company: 'X' } }),
});
expect(res.status).toBe(400);
});
it('rejects when company is missing', async () => {
const res = await fetch(`${baseUrl}/api/access-requests`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ user_data: { name: 'Max', email: 'x@x.com' } }),
});
expect(res.status).toBe(400);
});
it('rejects empty body', async () => {
const res = await fetch(`${baseUrl}/api/access-requests`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({}),
});
expect(res.status).toBe(400);
});
});
describe('GET /api/access-requests (admin)', () => {
it('rejects without auth', async () => {
const res = await fetch(`${baseUrl}/api/access-requests`);
expect(res.status).toBe(401);
});
});
describe('PUT /api/access-requests/:id (admin)', () => {
it('rejects without auth', async () => {
const res = await fetch(`${baseUrl}/api/access-requests/fake-id`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ status: 'approved' }),
});
expect(res.status).toBe(401);
});
});
});
+10
View File
@@ -0,0 +1,10 @@
import { defineConfig } from 'vitest/config'
import react from '@vitejs/plugin-react'
export default defineConfig({
plugins: [react()],
test: {
environment: 'jsdom',
globals: true,
},
})
+778
View File
@@ -0,0 +1,778 @@
#!/bin/sh
set -e
# Docker Engine for Linux installation script.
#
# This script is intended as a convenient way to configure docker's package
# repositories and to install Docker Engine, This script is not recommended
# for production environments. Before running this script, make yourself familiar
# with potential risks and limitations, and refer to the installation manual
# at https://docs.docker.com/engine/install/ for alternative installation methods.
#
# The script:
#
# - Requires `root` or `sudo` privileges to run.
# - Attempts to detect your Linux distribution and version and configure your
# package management system for you.
# - Doesn't allow you to customize most installation parameters.
# - Installs dependencies and recommendations without asking for confirmation.
# - Installs the latest stable release (by default) of Docker CLI, Docker Engine,
# Docker Buildx, Docker Compose, containerd, and runc. When using this script
# to provision a machine, this may result in unexpected major version upgrades
# of these packages. Always test upgrades in a test environment before
# deploying to your production systems.
# - Isn't designed to upgrade an existing Docker installation. When using the
# script to update an existing installation, dependencies may not be updated
# to the expected version, resulting in outdated versions.
#
# Source code is available at https://github.com/docker/docker-install/
#
# Usage
# ==============================================================================
#
# To install the latest stable versions of Docker CLI, Docker Engine, and their
# dependencies:
#
# 1. download the script
#
# $ curl -fsSL https://get.docker.com -o install-docker.sh
#
# 2. verify the script's content
#
# $ cat install-docker.sh
#
# 3. run the script with --dry-run to verify the steps it executes
#
# $ sh install-docker.sh --dry-run
#
# 4. run the script either as root, or using sudo to perform the installation.
#
# $ sudo sh install-docker.sh
#
# Command-line options
# ==============================================================================
#
# --version <VERSION>
# Use the --version option to install a specific version, for example:
#
# $ sudo sh install-docker.sh --version 23.0
#
# --channel <stable|test>
#
# Use the --channel option to install from an alternative installation channel.
# The following example installs the latest versions from the "test" channel,
# which includes pre-releases (alpha, beta, rc):
#
# $ sudo sh install-docker.sh --channel test
#
# Alternatively, use the script at https://test.docker.com, which uses the test
# channel as default.
#
# --mirror <Aliyun|AzureChinaCloud>
#
# Use the --mirror option to install from a mirror supported by this script.
# Available mirrors are "Aliyun" (https://mirrors.aliyun.com/docker-ce), and
# "AzureChinaCloud" (https://mirror.azure.cn/docker-ce), for example:
#
# $ sudo sh install-docker.sh --mirror AzureChinaCloud
#
# --setup-repo
#
# Use the --setup-repo option to configure Docker's package repositories without
# installing Docker packages. This is useful when you want to add the repository
# but install packages separately:
#
# $ sudo sh install-docker.sh --setup-repo
#
# Automatic Service Start
#
# By default, this script automatically starts the Docker daemon and enables the docker
# service after installation if systemd is used as init.
#
# If you prefer to start the service manually, use the --no-autostart option:
#
# $ sudo sh install-docker.sh --no-autostart
#
# Note: Starting the service requires appropriate privileges to manage system services.
#
# ==============================================================================
# Git commit from https://github.com/docker/docker-install when
# the script was uploaded (Should only be modified by upload job):
SCRIPT_COMMIT_SHA="02cb80d6c7d24c85a458ae31d166a6c535c7a37a"
# strip "v" prefix if present
VERSION="${VERSION#v}"
# The channel to install from:
# * stable
# * test
DEFAULT_CHANNEL_VALUE="stable"
if [ -z "$CHANNEL" ]; then
CHANNEL=$DEFAULT_CHANNEL_VALUE
fi
DEFAULT_DOWNLOAD_URL="https://download.docker.com"
if [ -z "$DOWNLOAD_URL" ]; then
DOWNLOAD_URL=$DEFAULT_DOWNLOAD_URL
fi
DEFAULT_REPO_FILE="docker-ce.repo"
if [ -z "$REPO_FILE" ]; then
REPO_FILE="$DEFAULT_REPO_FILE"
# Automatically default to a staging repo fora
# a staging download url (download-stage.docker.com)
case "$DOWNLOAD_URL" in
*-stage*) REPO_FILE="docker-ce-staging.repo";;
esac
fi
mirror=''
DRY_RUN=${DRY_RUN:-}
REPO_ONLY=${REPO_ONLY:-0}
NO_AUTOSTART=${NO_AUTOSTART:-0}
while [ $# -gt 0 ]; do
case "$1" in
--channel)
CHANNEL="$2"
shift
;;
--dry-run)
DRY_RUN=1
;;
--mirror)
mirror="$2"
shift
;;
--version)
VERSION="${2#v}"
shift
;;
--setup-repo)
REPO_ONLY=1
shift
;;
--no-autostart)
NO_AUTOSTART=1
;;
--*)
echo "Illegal option $1"
;;
esac
shift $(( $# > 0 ? 1 : 0 ))
done
case "$mirror" in
Aliyun)
DOWNLOAD_URL="https://mirrors.aliyun.com/docker-ce"
;;
AzureChinaCloud)
DOWNLOAD_URL="https://mirror.azure.cn/docker-ce"
;;
"")
;;
*)
>&2 echo "unknown mirror '$mirror': use either 'Aliyun', or 'AzureChinaCloud'."
exit 1
;;
esac
case "$CHANNEL" in
stable|test)
;;
*)
>&2 echo "unknown CHANNEL '$CHANNEL': use either stable or test."
exit 1
;;
esac
command_exists() {
command -v "$@" > /dev/null 2>&1
}
# version_gte checks if the version specified in $VERSION is at least the given
# SemVer (Maj.Minor[.Patch]), or CalVer (YY.MM) version.It returns 0 (success)
# if $VERSION is either unset (=latest) or newer or equal than the specified
# version, or returns 1 (fail) otherwise.
#
# examples:
#
# VERSION=23.0
# version_gte 23.0 // 0 (success)
# version_gte 20.10 // 0 (success)
# version_gte 19.03 // 0 (success)
# version_gte 26.1 // 1 (fail)
version_gte() {
if [ -z "$VERSION" ]; then
return 0
fi
version_compare "$VERSION" "$1"
}
# version_compare compares two version strings (either SemVer (Major.Minor.Path),
# or CalVer (YY.MM) version strings. It returns 0 (success) if version A is newer
# or equal than version B, or 1 (fail) otherwise. Patch releases and pre-release
# (-alpha/-beta) are not taken into account
#
# examples:
#
# version_compare 23.0.0 20.10 // 0 (success)
# version_compare 23.0 20.10 // 0 (success)
# version_compare 20.10 19.03 // 0 (success)
# version_compare 20.10 20.10 // 0 (success)
# version_compare 19.03 20.10 // 1 (fail)
version_compare() (
set +x
yy_a="$(echo "$1" | cut -d'.' -f1)"
yy_b="$(echo "$2" | cut -d'.' -f1)"
if [ "$yy_a" -lt "$yy_b" ]; then
return 1
fi
if [ "$yy_a" -gt "$yy_b" ]; then
return 0
fi
mm_a="$(echo "$1" | cut -d'.' -f2)"
mm_b="$(echo "$2" | cut -d'.' -f2)"
# trim leading zeros to accommodate CalVer
mm_a="${mm_a#0}"
mm_b="${mm_b#0}"
if [ "${mm_a:-0}" -lt "${mm_b:-0}" ]; then
return 1
fi
return 0
)
is_dry_run() {
if [ -z "$DRY_RUN" ]; then
return 1
else
return 0
fi
}
is_wsl() {
case "$(uname -r)" in
*microsoft* ) true ;; # WSL 2
*Microsoft* ) true ;; # WSL 1
* ) false;;
esac
}
is_darwin() {
case "$(uname -s)" in
*darwin* ) true ;;
*Darwin* ) true ;;
* ) false;;
esac
}
deprecation_notice() {
distro=$1
distro_version=$2
echo
printf "\033[91;1mDEPRECATION WARNING\033[0m\n"
printf " This Linux distribution (\033[1m%s %s\033[0m) reached end-of-life and is no longer supported by this script.\n" "$distro" "$distro_version"
echo " No updates or security fixes will be released for this distribution, and users are recommended"
echo " to upgrade to a currently maintained version of $distro."
echo
printf "Press \033[1mCtrl+C\033[0m now to abort this script, or wait for the installation to continue."
echo
sleep 10
}
get_distribution() {
lsb_dist=""
# Every system that we officially support has /etc/os-release
if [ -r /etc/os-release ]; then
lsb_dist="$(. /etc/os-release && echo "$ID")"
fi
# Normalize Fedora Asahi Remix to fedora
if [ "$lsb_dist" = "fedora-asahi-remix" ]; then
lsb_dist="fedora"
fi
# Returning an empty string here should be alright since the
# case statements don't act unless you provide an actual value
echo "$lsb_dist"
}
start_docker_daemon() {
# Use systemctl if available (for systemd-based systems)
if command_exists systemctl; then
is_dry_run || >&2 echo "Using systemd to manage Docker service"
if (
is_dry_run || set -x
$sh_c "systemctl enable --now docker.service 2>/dev/null"
); then
is_dry_run || echo "INFO: Docker daemon enabled and started" >&2
else
is_dry_run || echo "WARNING: unable to enable the docker service" >&2
fi
else
# No service management available (container environment)
if ! is_dry_run; then
>&2 echo "Note: Running in a container environment without service management"
>&2 echo "Docker daemon cannot be started automatically in this environment"
>&2 echo "The Docker packages have been installed successfully"
fi
fi
>&2 echo
}
echo_docker_as_nonroot() {
if is_dry_run; then
return
fi
if command_exists docker && [ -e /var/run/docker.sock ]; then
(
set -x
$sh_c 'docker version'
) || true
fi
# intentionally mixed spaces and tabs here -- tabs are stripped by "<<-EOF", spaces are kept in the output
echo
echo "================================================================================"
echo
if version_gte "20.10"; then
echo "To run Docker as a non-privileged user, consider setting up the"
echo "Docker daemon in rootless mode for your user:"
echo
echo " dockerd-rootless-setuptool.sh install"
echo
echo "Visit https://docs.docker.com/go/rootless/ to learn about rootless mode."
echo
fi
echo
echo "To run the Docker daemon as a fully privileged service, but granting non-root"
echo "users access, refer to https://docs.docker.com/go/daemon-access/"
echo
echo "WARNING: Access to the remote API on a privileged Docker daemon is equivalent"
echo " to root access on the host. Refer to the 'Docker daemon attack surface'"
echo " documentation for details: https://docs.docker.com/go/attack-surface/"
echo
echo "================================================================================"
echo
}
# Check if this is a forked Linux distro
check_forked() {
# Check for lsb_release command existence, it usually exists in forked distros
if command_exists lsb_release; then
# Check if the `-u` option is supported
set +e
lsb_release -a -u > /dev/null 2>&1
lsb_release_exit_code=$?
set -e
# Check if the command has exited successfully, it means we're in a forked distro
if [ "$lsb_release_exit_code" = "0" ]; then
# Print info about current distro
cat <<-EOF
You're using '$lsb_dist' version '$dist_version'.
EOF
# Get the upstream release info
lsb_dist=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'id' | cut -d ':' -f 2 | tr -d '[:space:]')
dist_version=$(lsb_release -a -u 2>&1 | tr '[:upper:]' '[:lower:]' | grep -E 'codename' | cut -d ':' -f 2 | tr -d '[:space:]')
# Print info about upstream distro
cat <<-EOF
Upstream release is '$lsb_dist' version '$dist_version'.
EOF
else
if [ -r /etc/debian_version ] && [ "$lsb_dist" != "ubuntu" ] && [ "$lsb_dist" != "raspbian" ]; then
if [ "$lsb_dist" = "osmc" ]; then
# OSMC runs Raspbian
lsb_dist=raspbian
else
# We're Debian and don't even know it!
lsb_dist=debian
fi
dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
case "$dist_version" in
13|14|forky)
dist_version="trixie"
;;
12)
dist_version="bookworm"
;;
11)
dist_version="bullseye"
;;
10)
dist_version="buster"
;;
9)
dist_version="stretch"
;;
8)
dist_version="jessie"
;;
esac
fi
fi
fi
}
do_install() {
echo "# Executing docker install script, commit: $SCRIPT_COMMIT_SHA"
if [ "$REPO_ONLY" != "1" ] && command_exists docker; then
cat >&2 <<-'EOF'
Warning: the "docker" command appears to already exist on this system.
If you already have Docker installed, this script can cause trouble, which is
why we're displaying this warning and provide the opportunity to cancel the
installation.
If you installed the current Docker package using this script and are using it
again to update Docker, you can ignore this message, but be aware that the
script resets any custom changes in the deb and rpm repo configuration
files to match the parameters passed to the script.
You may press Ctrl+C now to abort this script.
EOF
( set -x; sleep 20 )
fi
user="$(id -un 2>/dev/null || true)"
sh_c='sh -c'
if [ "$user" != 'root' ]; then
if command_exists sudo; then
sh_c='sudo -E sh -c'
elif command_exists su; then
sh_c='su -c'
else
cat >&2 <<-'EOF'
Error: this installer needs the ability to run commands as root.
We are unable to find either "sudo" or "su" available to make this happen.
EOF
exit 1
fi
fi
if is_dry_run; then
sh_c="echo"
fi
# perform some very rudimentary platform detection
lsb_dist=$( get_distribution )
lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"
if is_wsl; then
echo
echo "WSL DETECTED: We recommend using Docker Desktop for Windows."
echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop/"
echo
cat >&2 <<-'EOF'
You may press Ctrl+C now to abort this script.
EOF
( set -x; sleep 20 )
fi
case "$lsb_dist" in
ubuntu)
if command_exists lsb_release; then
dist_version="$(lsb_release --codename | cut -f2)"
fi
if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then
dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"
fi
;;
debian|raspbian)
dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
case "$dist_version" in
13)
dist_version="trixie"
;;
12)
dist_version="bookworm"
;;
11)
dist_version="bullseye"
;;
10)
dist_version="buster"
;;
9)
dist_version="stretch"
;;
8)
dist_version="jessie"
;;
esac
;;
centos|rhel|rocky)
if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
fi
;;
*)
if command_exists lsb_release; then
dist_version="$(lsb_release --release | cut -f2)"
fi
if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
fi
;;
esac
# Check if this is a forked Linux distro
check_forked
# Print deprecation warnings for distro versions that recently reached EOL,
# but may still be commonly used (especially LTS versions).
case "$lsb_dist.$dist_version" in
centos.8|centos.7|rhel.7)
deprecation_notice "$lsb_dist" "$dist_version"
;;
debian.buster|debian.stretch|debian.jessie)
deprecation_notice "$lsb_dist" "$dist_version"
;;
raspbian.buster|raspbian.stretch|raspbian.jessie)
deprecation_notice "$lsb_dist" "$dist_version"
;;
ubuntu.focal|ubuntu.bionic|ubuntu.xenial|ubuntu.trusty)
deprecation_notice "$lsb_dist" "$dist_version"
;;
ubuntu.oracular|ubuntu.mantic|ubuntu.lunar|ubuntu.kinetic|ubuntu.impish|ubuntu.hirsute|ubuntu.groovy|ubuntu.eoan|ubuntu.disco|ubuntu.cosmic)
deprecation_notice "$lsb_dist" "$dist_version"
;;
fedora.*)
if [ "$dist_version" -lt 43 ]; then
deprecation_notice "$lsb_dist" "$dist_version"
fi
;;
esac
# Run setup for each distro accordingly
case "$lsb_dist" in
ubuntu|debian|raspbian)
pre_reqs="ca-certificates curl"
apt_repo_lsb_dist="$lsb_dist"
# Docker does not publish a Raspbian Trixie repo; use Debian Trixie instead.
if [ "$lsb_dist" = "raspbian" ] && [ "$dist_version" = "trixie" ]; then
apt_repo_lsb_dist="debian"
fi
apt_repo="deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] $DOWNLOAD_URL/linux/$apt_repo_lsb_dist $dist_version $CHANNEL"
(
if ! is_dry_run; then
set -x
fi
$sh_c 'apt-get -qq update >/dev/null'
$sh_c "DEBIAN_FRONTEND=noninteractive apt-get -y -qq install $pre_reqs >/dev/null"
$sh_c 'install -m 0755 -d /etc/apt/keyrings'
$sh_c "curl -fsSL \"$DOWNLOAD_URL/linux/$apt_repo_lsb_dist/gpg\" -o /etc/apt/keyrings/docker.asc"
$sh_c "chmod a+r /etc/apt/keyrings/docker.asc"
$sh_c "echo \"$apt_repo\" > /etc/apt/sources.list.d/docker.list"
$sh_c 'apt-get -qq update >/dev/null'
)
if [ "$REPO_ONLY" = "1" ]; then
exit 0
fi
pkg_version=""
cli_pkg_version=""
if [ -n "$VERSION" ]; then
if is_dry_run; then
echo "# WARNING: VERSION pinning is not supported in DRY_RUN"
else
# Will work for incomplete versions IE (17.12), but may not actually grab the "latest" if in the test channel
pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/~ce~.*/g' | sed 's/-/.*/g')"
search_command="apt-cache madison docker-ce | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3"
echo "INFO: Searching repository for VERSION '$VERSION'"
echo "INFO: $search_command"
pkg_version="$($sh_c "$search_command")"
if [ -z "$pkg_version" ]; then
echo
echo "ERROR: '$VERSION' not found amongst apt-cache madison results"
echo
exit 1
fi
pkg_version="=$pkg_version"
if version_gte "18.09"; then
search_command="apt-cache madison docker-ce-cli | grep '$pkg_pattern' | head -1 | awk '{\$1=\$1};1' | cut -d' ' -f 3"
echo "INFO: $search_command"
cli_pkg_version="$($sh_c "$search_command")"
if [ -n "$cli_pkg_version" ]; then
cli_pkg_version="=$cli_pkg_version"
fi
fi
fi
fi
(
pkgs="docker-ce${pkg_version}"
if version_gte "18.09"; then
# older versions didn't ship the cli and containerd as separate packages
pkgs="$pkgs docker-ce-cli${cli_pkg_version} containerd.io"
fi
if version_gte "20.10"; then
pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"
fi
if version_gte "23.0"; then
pkgs="$pkgs docker-buildx-plugin"
fi
if version_gte "28.2"; then
pkgs="$pkgs docker-model-plugin"
fi
if ! is_dry_run; then
set -x
fi
$sh_c "DEBIAN_FRONTEND=noninteractive apt-get -y -qq install $pkgs >/dev/null"
)
if [ "$NO_AUTOSTART" != "1" ]; then
start_docker_daemon
fi
echo_docker_as_nonroot
exit 0
;;
centos|fedora|rhel|rocky)
repo_file_url="$DOWNLOAD_URL/linux/$lsb_dist/$REPO_FILE"
(
if ! is_dry_run; then
set -x
fi
if command_exists dnf5; then
$sh_c "dnf -y -q --setopt=install_weak_deps=False install dnf-plugins-core"
$sh_c "dnf5 config-manager addrepo --overwrite --save-filename=docker-ce.repo --from-repofile='$repo_file_url'"
if [ "$CHANNEL" != "stable" ]; then
$sh_c "dnf5 config-manager setopt \"docker-ce-*.enabled=0\""
$sh_c "dnf5 config-manager setopt \"docker-ce-$CHANNEL.enabled=1\""
fi
$sh_c "dnf makecache"
elif command_exists dnf; then
$sh_c "dnf -y -q --setopt=install_weak_deps=False install dnf-plugins-core"
$sh_c "rm -f /etc/yum.repos.d/docker-ce.repo /etc/yum.repos.d/docker-ce-staging.repo"
$sh_c "dnf config-manager --add-repo $repo_file_url"
if [ "$CHANNEL" != "stable" ]; then
$sh_c "dnf config-manager --set-disabled \"docker-ce-*\""
$sh_c "dnf config-manager --set-enabled \"docker-ce-$CHANNEL\""
fi
$sh_c "dnf makecache"
else
$sh_c "yum -y -q install yum-utils"
$sh_c "rm -f /etc/yum.repos.d/docker-ce.repo /etc/yum.repos.d/docker-ce-staging.repo"
$sh_c "yum-config-manager --add-repo $repo_file_url"
if [ "$CHANNEL" != "stable" ]; then
$sh_c "yum-config-manager --disable \"docker-ce-*\""
$sh_c "yum-config-manager --enable \"docker-ce-$CHANNEL\""
fi
$sh_c "yum makecache"
fi
)
if [ "$REPO_ONLY" = "1" ]; then
exit 0
fi
pkg_version=""
cli_pkg_version=""
if command_exists dnf; then
pkg_manager="dnf"
pkg_manager_flags="-y -q --best"
else
pkg_manager="yum"
pkg_manager_flags="-y -q"
fi
if [ -n "$VERSION" ]; then
if is_dry_run; then
echo "# WARNING: VERSION pinning is not supported in DRY_RUN"
else
if [ "$lsb_dist" = "fedora" ]; then
pkg_suffix="fc$dist_version"
else
pkg_suffix="el"
fi
pkg_pattern="$(echo "$VERSION" | sed 's/-ce-/\\\\.ce.*/g' | sed 's/-/.*/g').*$pkg_suffix"
search_command="$pkg_manager list --showduplicates docker-ce | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'"
echo "INFO: Searching repository for VERSION '$VERSION'"
echo "INFO: $search_command"
pkg_version="$($sh_c "$search_command")"
if [ -z "$pkg_version" ]; then
echo
echo "ERROR: '$VERSION' not found amongst $pkg_manager list results"
echo
exit 1
fi
# Cut out the epoch and prefix with a '-'
pkg_version="-$(echo "$pkg_version" | cut -d':' -f 2)"
if version_gte "18.09"; then
# older versions don't support a cli package
search_command="$pkg_manager list --showduplicates docker-ce-cli | grep '$pkg_pattern' | tail -1 | awk '{print \$2}'"
cli_pkg_version="$($sh_c "$search_command" | cut -d':' -f 2)"
fi
fi
fi
(
pkgs="docker-ce$pkg_version"
if version_gte "18.09"; then
# older versions didn't ship the cli and containerd as separate packages
if [ -n "$cli_pkg_version" ]; then
pkgs="$pkgs docker-ce-cli-$cli_pkg_version containerd.io"
else
pkgs="$pkgs docker-ce-cli containerd.io"
fi
fi
if version_gte "20.10"; then
pkgs="$pkgs docker-compose-plugin docker-ce-rootless-extras$pkg_version"
fi
if version_gte "23.0"; then
pkgs="$pkgs docker-buildx-plugin docker-model-plugin"
fi
if ! is_dry_run; then
set -x
fi
$sh_c "$pkg_manager $pkg_manager_flags install $pkgs"
)
if [ "$NO_AUTOSTART" != "1" ]; then
start_docker_daemon
fi
echo_docker_as_nonroot
exit 0
;;
sles)
echo "Effective v27.5, please consult SLES distro statement for s390x support."
exit 1
;;
*)
if [ -z "$lsb_dist" ]; then
if is_darwin; then
echo
echo "ERROR: Unsupported operating system 'macOS'"
echo "Please get Docker Desktop from https://www.docker.com/products/docker-desktop"
echo
exit 1
fi
fi
echo
echo "ERROR: Unsupported distribution '$lsb_dist'"
echo
exit 1
;;
esac
exit 1
}
# wrapped up in a function so that we have some protection against only getting
# half the file during "curl | sh"
do_install
+52
View File
@@ -0,0 +1,52 @@
import sys
from pathlib import Path
from datetime import date
import logging
logging.basicConfig(level=logging.INFO)
# Add monorepo-cli src to path
sys.path.insert(0, "/home/andre/coden/Orchestrator/shared/tools/monorepo-cli/src")
try:
from monorepo.knowledge.sources.pdf import PDFSource
from monorepo.knowledge.sources.docx import DocxSource
from monorepo.knowledge.sources.base import SourceConfig
except ImportError as e:
print(f"Import error: {e}")
sys.exit(1)
target_dir = Path("/home/andre/coden/Orchestrator/privat/CV/andreknie.de/content/kniepunkt/")
target_dir.mkdir(parents=True, exist_ok=True)
source_dir = Path("/home/andre/coden/Kniepunkt/KNIEPUNKTe")
print("Extracting PDFs...")
pdf_source = PDFSource()
pdf_config = SourceConfig(name="pdf_kniepunkte", type="pdf", params={"directory": str(source_dir)})
pdf_result = pdf_source.extract(pdf_config, "privat")
print("Extracting DOCXs...")
docx_source = DocxSource()
docx_config = SourceConfig(name="docx_kniepunkte", type="docx", params={"directory": str(source_dir)})
docx_result = docx_source.extract(docx_config, "privat")
artifacts = pdf_result.artifacts + docx_result.artifacts
print(f"Extracted {len(artifacts)} artifacts.")
for artifact in artifacts:
title = artifact.metadata.title
content = artifact.content
fm = f"---\ntitle: \"{title}\"\ndate: {date.today().isoformat()}\n---\n\n"
# Safe filename
safe_title = "".join(c for c in title if c.isalnum() or c in " -_").strip().replace(" ", "-")
if not safe_title:
safe_title = artifact.file_path.stem
target_path = target_dir / f"{safe_title}.md"
target_path.write_text(fm + content, encoding="utf-8")
print(f"Written {target_path}")
print("Done.")
+97
View File
@@ -0,0 +1,97 @@
import os
from PIL import Image
from pathlib import Path
BASE_DIR = Path("/home/andre/coden/Orchestrator/privat/CV/andreknie.de")
DIRS_TO_PROCESS = [
BASE_DIR / "public/images",
BASE_DIR / "public/logos"
]
def optimize_images():
for img_dir in DIRS_TO_PROCESS:
if not img_dir.exists():
continue
# Process files directly in this directory (not recursive to avoid processing kniepunkt again)
for img_path in img_dir.iterdir():
if img_path.is_file() and img_path.suffix.lower() in [".png", ".jpg", ".jpeg"]:
if img_path.name == "favicon.png":
continue
try:
with Image.open(img_path) as img:
# Convert to RGB if necessary
if img.mode in ("RGBA", "P"):
img = img.convert("RGBA")
elif img.mode != "RGB":
img = img.convert("RGB")
# Resize if overly large
if img.width > 2000:
ratio = 2000 / img.width
new_size = (2000, int(img.height * ratio))
img = img.resize(new_size, Image.Resampling.LANCZOS)
webp_path = img_path.with_suffix(".webp")
img.save(webp_path, "WEBP", quality=80)
img_path.unlink()
print(f"Optimized: {img_path.name} -> {webp_path.name}")
except Exception as e:
print(f"Error processing {img_path}: {e}")
def update_references():
import glob
# Search all jsx, css, yaml, md files
extensions = ["jsx", "css", "yaml", "yml", "md"]
search_dirs = [
BASE_DIR / "src",
BASE_DIR / "content"
]
# Also update index.html if needed (though favicon.png is excluded from conversion)
for d in search_dirs:
for root, _, files in os.walk(d):
for file in files:
ext = file.split('.')[-1].lower()
if ext in extensions:
filepath = Path(root) / file
try:
content = filepath.read_text(encoding="utf-8")
# Replace .png, .jpg, .jpeg with .webp
# But be careful not to replace favicon.png if it's there
if "favicon.png" not in content:
new_content = content.replace(".png", ".webp").replace(".jpg", ".webp").replace(".jpeg", ".webp")
if new_content != content:
filepath.write_text(new_content, encoding="utf-8")
print(f"Updated references in: {filepath.name}")
else:
# Do a safe replace (not touching favicon.png)
lines = content.split('\n')
new_lines = []
changed = False
for line in lines:
if "favicon.png" not in line:
nl = line.replace(".png", ".webp").replace(".jpg", ".webp").replace(".jpeg", ".webp")
if nl != line:
changed = True
new_lines.append(nl)
else:
new_lines.append(line)
if changed:
filepath.write_text('\n'.join(new_lines), encoding="utf-8")
print(f"Updated references in: {filepath.name} (safe mode)")
except Exception as e:
pass
if __name__ == "__main__":
optimize_images()
update_references()
print("Optimization complete!")
@@ -0,0 +1,111 @@
name: Deploy CV Site (andreknie.de)
on:
push:
branches:
- master
- main
workflow_dispatch:
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Code
uses: actions/checkout@v3
- name: Install & Build Frontend
run: |
npm ci
npm run build
node scripts/check-bundle.mjs
test -s dist/index.html
test -d dist/assets
test -n "$(find dist/assets -type f -print -quit)"
- name: Copy project files to VM
uses: appleboy/scp-action@v0.1.7
with:
host: ${{ secrets.DEPLOY_SSH_HOST }}
username: ${{ secrets.DEPLOY_SSH_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
source: "Caddyfile,docker-compose.yml,Dockerfile,server/**,package.json,package-lock.json,dist/**,dist/.*"
target: "/opt/orchestrator/privat/CV/andreknie.de"
- name: Execute Deployment on VM
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.DEPLOY_SSH_HOST }}
username: ${{ secrets.DEPLOY_SSH_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
set -Eeuo pipefail
cd /opt/orchestrator/privat/CV/andreknie.de
# 1. Sichere .env aus den Gitea Secrets generieren
cat <<EOF > .env
PORT=3003
NODE_ENV=production
BASE_URL=https://andreknie.de
SMTP_HOST=smtp.ionos.de
SMTP_PORT=587
SMTP_USER=${{ secrets.SMTP_USER }}
SMTP_PASS=${{ secrets.SMTP_PASS }}
STAKEHOLDER_EMAIL=kontakt@d-hive.de
DATABASE_URL=postgresql://umami:${{ secrets.UMAMI_DB_PASS }}@umami-db:5432/umami
POSTGRES_DB=umami
POSTGRES_USER=umami
POSTGRES_PASSWORD=${{ secrets.UMAMI_DB_PASS }}
HASH_SALT=${{ secrets.UMAMI_HASH_SALT }}
EOF
# 2. Vollständiges Frontend als begrenztes Release vorbereiten.
# Die Release-ID stammt aus dem Commit und bleibt rückverfolgbar.
test -s dist/index.html
test -d dist/assets
release_id="${{ github.sha }}"
test -n "$release_id"
case "$release_id" in
(*[!A-Za-z0-9._-]*) echo "Ungültige Release-ID"; exit 1 ;;
esac
release_dir="releases/release-${release_id}"
previous_dir="releases/previous"
mkdir -p releases
if [ -e "$release_dir" ]; then rm -rf -- "$release_dir"; fi
mkdir -p "$release_dir"
cp -a dist/. "$release_dir/"
test -s "$release_dir/index.html"
test -n "$(find "$release_dir/assets" -type f -print -quit)"
rollback() {
if [ -d "$previous_dir" ]; then
rm -rf -- site
mv -- "$previous_dir" site
echo "Rollback auf das vorherige Release ausgeführt."
fi
}
trap rollback ERR
if [ -e site ]; then
rm -rf -- "$previous_dir"
mv -- site "$previous_dir"
fi
mv -- "$release_dir" site
# Debugging: Zeige an, ob die Dateien wirklich da sind
echo "INHALT VON SITE:"
ls -la site/
# 3. Docker Container neustarten
docker compose up -d --build
echo "CADDYFILE CSP AUF HOST:"
grep -n "Content-Security-Policy" Caddyfile
echo "CADDYFILE CSP IM CONTAINER:"
docker compose exec -T caddy grep -n "Content-Security-Policy" /etc/caddy/Caddyfile
docker compose exec -T caddy caddy reload --config /etc/caddy/Caddyfile || true
docker compose up -d --force-recreate caddy
trap - ERR
# Abgebrochene temporäre Releases entfernen. Neben site bleibt
# höchstens ein klar benannter Rollback-Stand erhalten.
find releases -mindepth 1 -maxdepth 1 -type d -name 'release-*' -exec rm -rf -- {} +
@@ -0,0 +1,163 @@
name: Patch Server RAM Limits
on:
push:
branches:
- master
paths:
- 'privat/CV/andreknie.de/.gitea/workflows/patch-ram.yml'
workflow_dispatch:
jobs:
patch:
runs-on: ubuntu-latest
steps:
- name: Patch NoteGraph and OrgMyLife
uses: appleboy/ssh-action@v1.0.3
with:
host: ${{ secrets.DEPLOY_SSH_HOST }}
username: ${{ secrets.DEPLOY_SSH_USER }}
key: ${{ secrets.DEPLOY_SSH_KEY }}
script: |
echo "Patching NoteGraph..."
if [ -d /opt/NoteGraph ]; then
cd /opt/NoteGraph
cat << 'EOF' > docker-compose.yml
services:
silverbullet:
image: zefhemel/silverbullet:latest
restart: unless-stopped
deploy:
resources:
limits:
memory: 256M
environment:
SB_USER: "${SB_USER:-admin:changeme}"
volumes:
- ./notes:/space
ports:
- "3000:3000"
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000"]
interval: 30s
timeout: 5s
retries: 3
git-sync:
image: alpine/git:latest
restart: unless-stopped
deploy:
resources:
limits:
memory: 64M
volumes:
- ./notes:/space
- ./.git:/repo-git:ro
entrypoint: /bin/sh
command: |
-c '
cd /space
git init 2>/dev/null || true
git config user.name "NoteGraph Auto-Sync"
git config user.email "notegraph@andreknie.de"
while true; do
sleep 300
cd /space
git add -A
if ! git diff --cached --quiet 2>/dev/null; then
git commit -m "auto: sync notes \$(date +%Y-%m-%d_%H:%M)"
fi
done
'
ingestion:
build:
context: ./ingestion
restart: unless-stopped
deploy:
resources:
limits:
memory: 256M
ports:
- "8001:8001"
volumes:
- ./notes:/app/notes
- ./ingestion/inbox:/app/inbox
env_file:
- .env
environment:
NOTES_DIR: /app/notes
INBOX_DIR: /app/inbox
depends_on:
- silverbullet
EOF
docker compose up -d
fi
echo "Patching OrgMyLife..."
if [ -d /opt/OrgMyLife ]; then
cd /opt/OrgMyLife
cat << 'EOF' > docker-compose.yml
version: "3.8"
services:
db:
image: postgres:16-alpine
restart: unless-stopped
command: postgres -c shared_buffers=32MB -c max_connections=20
deploy:
resources:
limits:
memory: 256M
environment:
POSTGRES_DB: orgmylife
POSTGRES_USER: orgmylife
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-changeme}
volumes:
- pgdata:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U orgmylife"]
interval: 5s
timeout: 3s
retries: 5
app:
build: .
restart: unless-stopped
deploy:
resources:
limits:
memory: 256M
depends_on:
db:
condition: service_healthy
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql://orgmylife:${POSTGRES_PASSWORD:-changeme}@db:5432/orgmylife
NEXTCLOUD_URL: ${NEXTCLOUD_URL}
NEXTCLOUD_USERNAME: ${NEXTCLOUD_USERNAME}
NEXTCLOUD_PASSWORD: ${NEXTCLOUD_PASSWORD}
IMAP_SERVER: ${IMAP_SERVER}
IMAP_PORT: ${IMAP_PORT:-993}
EMAIL_USERNAME: ${EMAIL_USERNAME}
EMAIL_PASSWORD: ${EMAIL_PASSWORD}
EMAIL_WEBMAIL_URL: ${EMAIL_WEBMAIL_URL:-}
GMAIL_USERNAME: ${GMAIL_USERNAME:-}
GMAIL_PASSWORD: ${GMAIL_PASSWORD:-}
API_SECRET: ${API_SECRET:-}
APP_USERNAME: ${APP_USERNAME:-admin}
APP_PASSWORD: ${APP_PASSWORD:-changeme}
volumes:
- ./BACKLOG.md:/app/BACKLOG.md:ro
command: >
sh -c "python -c 'from app.db.session import engine, Base; from app.models import *; Base.metadata.create_all(bind=engine)' &&
uvicorn app.main:app --host 0.0.0.0 --port 8000"
volumes:
pgdata:
EOF
docker compose up -d
fi
+93
View File
@@ -0,0 +1,93 @@
stages:
- build
- test
- deploy
variables:
DEPLOY_HOST: "217.160.174.2"
DEPLOY_USER: "root"
DEPLOY_PATH: "/opt/andreknie"
.ssh_setup: &ssh_setup
before_script:
- apt-get update -qq && apt-get install -y openssh-client rsync
- install -d -m 700 ~/.ssh
- echo "$VPS_SSH_KEY" > ~/.ssh/deploy_key
- chmod 600 ~/.ssh/deploy_key
- ssh-keyscan -H "${DEPLOY_HOST}" > ~/.ssh/known_hosts
- chmod 600 ~/.ssh/known_hosts
build-frontend:
stage: build
image: node:20
script:
- cd privat/CV/andreknie.de
- npm ci
- npm run build
artifacts:
paths:
- privat/CV/andreknie.de/dist/
expire_in: 1 day
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'
changes:
- "privat/CV/andreknie.de/**/*"
deploy-andreknie:
stage: deploy
image: alpine:latest
<<: *ssh_setup
dependencies:
- build-frontend
rules:
- if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == "main"'
changes:
- "privat/CV/andreknie.de/**/*"
script:
- ssh -i ~/.ssh/deploy_key -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes "${DEPLOY_USER}@${DEPLOY_HOST}" "install -d -m 755 ${DEPLOY_PATH}/site ${DEPLOY_PATH}/server ${DEPLOY_PATH}/server/data"
- cd privat/CV/andreknie.de
- |
cat <<EOF > .env
PORT=3003
NODE_ENV=production
BASE_URL=https://andreknie.de
SMTP_HOST=$SMTP_HOST
SMTP_PORT=587
SMTP_USER=$SMTP_USER
SMTP_PASS=$SMTP_PASS
STAKEHOLDER_EMAIL=kontakt@d-hive.de
EOF
- rsync -az --delete -e "ssh -i ~/.ssh/deploy_key -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes" dist/ "${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH}/site/"
- rsync -az --delete -e "ssh -i ~/.ssh/deploy_key -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes" server/ "${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH}/server/"
- rsync -az -e "ssh -i ~/.ssh/deploy_key -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes" package.json package-lock.json Dockerfile docker-compose.yml Caddyfile .env "${DEPLOY_USER}@${DEPLOY_HOST}:${DEPLOY_PATH}/"
- ssh -i ~/.ssh/deploy_key -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes "${DEPLOY_USER}@${DEPLOY_HOST}" "cd ${DEPLOY_PATH} && docker compose up -d --build"
- ssh -i ~/.ssh/deploy_key -o BatchMode=yes -o IdentitiesOnly=yes -o StrictHostKeyChecking=yes "${DEPLOY_USER}@${DEPLOY_HOST}" "cd ${DEPLOY_PATH} && docker compose exec caddy caddy reload --config /etc/caddy/Caddyfile"
- echo "Deployment finished. Caddy configuration reloaded successfully."
smoketest:
stage: test
image: node:20
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
script:
- cd privat/CV/andreknie.de
- npm ci
- node scripts/smoketest.js
artifacts:
paths:
- privat/CV/andreknie.de/public-dashboard/
expire_in: 1 week
pages:
stage: deploy
image: alpine:latest
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
dependencies:
- smoketest
script:
- mv privat/CV/andreknie.de/public-dashboard public
artifacts:
paths:
- public
expire_in: 1 week
+12 -3
View File
@@ -1,5 +1,9 @@
andreknie.de {
root * /opt/andreknie/site
www.andreknie.de {
redir https://andreknie.de{uri}
}
localhost, andreknie.de {
root * /dist
encode zstd gzip
header {
@@ -8,10 +12,11 @@ andreknie.de {
X-Frame-Options "DENY"
Referrer-Policy "strict-origin-when-cross-origin"
Permissions-Policy "camera=(), geolocation=(), microphone=()"
Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' https://stats.andreknie.de; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; img-src 'self' data: https:; font-src 'self' data: https://fonts.gstatic.com; connect-src 'self' https://stats.andreknie.de; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none'"
}
handle /api/* {
reverse_proxy localhost:3003
reverse_proxy backend:3003
}
@assets path /assets/*
@@ -26,3 +31,7 @@ andreknie.de {
file_server
}
}
stats.andreknie.de {
reverse_proxy umami:3000
}
@@ -0,0 +1,763 @@
# andreknie.de Findings Remediation Plan
Status: Umsetzungsanleitung, noch nicht abgearbeitet
Zielgruppe: Nachfolgendes Codex-Modell, insbesondere Luna
Letzter Review: 2026-07-28
## 1. Auftrag und Arbeitsgrenzen
Dieser Plan beschreibt die schrittweise Behebung der Findings aus dem vollstaendigen
Review aller Seiten, Komponenten und relevanten Backend-Flows von andreknie.de.
Wichtig:
- Nicht alle Arbeitspakete auf einmal umsetzen.
- Zu Beginn eines neuen Tasks genau ein vom Benutzer ausgewaehltes Arbeitspaket
bearbeiten.
- Vor der Implementierung den aktuellen Stand erneut lesen und die Findings
verifizieren.
- Keine unaufgeforderten Refactorings ausserhalb des ausgewaehlten Pakets.
- Bestehende Benutzer-Aenderungen im Worktree nicht zuruecksetzen.
- Keine echten Kontakt-, Newsletter- oder Speaker-CV-Anfragen in Produktion
absenden.
- Personenbezogene Produktionsdaten niemals in Logs, Antworten, Screenshots,
Commits oder Test-Fixtures uebernehmen.
## 2. Verbindlicher Repository-Kontext
### 2.1 Source of Truth
Arbeitsverzeichnis:
```text
C:\Coding\Orchestrator
```
Component:
```text
C:\Coding\Orchestrator\privat\CV\andreknie.de
```
Hub:
```text
https://git.d-hive.de/ankn/Orchestrator.git
```
Foederiertes Spoke-Repository:
```text
https://git.d-hive.de/dHive/andreknie.de.git
```
Nicht verwenden:
- Das alte GitHub-Repository. Es ist veraltet.
- Eine separate lokale Clone-Kopie von andreknie.de.
- Direkte Aenderungen ausserhalb des Orchestrator-Monorepos.
### 2.2 Vor jeder Arbeit lesen
Vom Orchestrator-Root:
```text
AGENTS.md
.agents/AGENTS.md
.kiro/steering/*.md
privat/CV/andreknie.de/README.md
privat/CV/andreknie.de/DEPLOYMENT-PLAN.md
privat/CV/andreknie.de/.gitea/workflows/deploy.yml
privat/CV/andreknie.de/FINDINGS-REMEDIATION-PLAN.md
```
Dabei haben die aktuellen System- und Benutzeranweisungen Vorrang. Fuer
versionierte Aenderungen gilt der in den Repository-Regeln beschriebene
Feature-Branch-, Commit-, Push- und Pull-/Merge-Request-Ablauf. Nicht direkt auf
`master` oder `main` pushen.
### 2.3 Gitea und Foederation
- Gitea wird ueber `tea` mit Browser-Authentifizierung verwendet.
- Lokales Tool:
```text
C:\Coding\tools\tea\tea.exe
```
- Gitea-Login: `dhive`
- Der Runner arbeitet im foederierten Spoke.
- Deployment erst nach erfolgreichem Review und Merge.
- Vor einem Deployment die aktuellen Orchestrator-/Federationsanleitungen
erneut lesen. Keine eigene Synchronisationsvariante erfinden.
- Workflow-Status nach dem Merge im Spoke mit `tea actions runs` pruefen.
- Live-Deployment erst als erfolgreich melden, wenn der Gitea-Run erfolgreich
ist und die konkrete Aenderung auf `https://andreknie.de` verifiziert wurde.
## 3. Technischer Ausgangspunkt
Stack:
- React 19
- React Router 7
- Vite 8
- Express 5
- Caddy
- Datei-basiertes CMS aus Markdown und YAML
- Gitea Actions Deployment
Relevante Befehle im Component-Verzeichnis:
```powershell
& 'C:\Users\knie\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\fallback\pnpm.cmd' run build
& 'C:\Users\knie\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\fallback\pnpm.cmd' run test
.\node_modules\.bin\eslint.CMD src server plugins vite.config.js
```
Hinweise:
- Der volle Lint ueber das gesamte Repository erfasst alte generierte Dateien
unter `site/assets` und ist deshalb fuer gezielte Source-Pruefungen nicht
aussagekraeftig.
- Fuer UI-Tests den lokalen Vite-Server starten und Desktop sowie Mobil mit
Browser-Automation pruefen.
- Relevante Viewports:
- Desktop: 1440 x 900
- Mobile: 375 x 844
- Mobile: 390 x 844
- Mobile: 430 x 932
- Nach Tests alle selbst gestarteten lokalen Server beenden.
## 4. Allgemeiner Ablauf fuer jedes Arbeitspaket
1. Repository-Regeln und diesen Plan lesen.
2. `git status --short --branch` im Orchestrator pruefen.
3. Bei fremden Aenderungen nicht zuruecksetzen; Ueberschneidungen sorgfaeltig
analysieren.
4. Aktuellen Hub-Stand per Fast-Forward aktualisieren.
5. Einen aussagekraeftigen Feature-Branch erstellen.
6. Nur die Dateien des ausgewaehlten Arbeitspakets bearbeiten.
7. Relevante Unit-, Integrations- und Browser-Tests ausfuehren.
8. Build und gezielten Source-Lint ausfuehren.
9. Diff auf Scope, Secrets, generierte Artefakte und unbeabsichtigte
Content-Aenderungen pruefen.
10. Conventional Commit erstellen.
11. Branch zum Gitea-Hub pushen und Pull-/Merge-Request erstellen.
12. PR/MR pruefen; nicht ohne erfolgreiche Quality Gates mergen.
13. Nach Freigabe mergen und den dokumentierten Hub-and-Spoke-
Federationsablauf ausfuehren.
14. Gitea-Deployment beobachten.
15. Live nur die betroffenen Funktionen read-only pruefen. Keine echten
Formulare absenden.
## 5. Prioritaet 1: Datenschutz und Ausfallsicherheit
Branch-Vorschlag:
```text
fix/andreknie-data-lifecycle
```
### 5.1 Token-Lebenszyklus korrigieren
Betroffene Dateien:
```text
server/services/confirmationToken.js
server/routes/contact.js
server/routes/talk-request.js
server/routes/newsletter.js
src/pages/Datenschutz.jsx
```
Aktuelles Problem:
- Bestaetigte Tokens bleiben durch die Cleanup-Bedingung dauerhaft erhalten.
- Die Token-Datei enthaelt personenbezogene Formulardaten.
- Bestaetigte Tokens werden vor erfolgreichem Abschluss des Folgeprozesses
verbraucht.
Umsetzung:
1. Token-Zustaende explizit modellieren, mindestens `pending` und `processing`.
2. Eine atomare Funktion einfuehren, die einen gueltigen Token fuer die
Verarbeitung reserviert, ihn aber noch nicht endgueltig entfernt.
3. Nach erfolgreichem Folgeprozess den Token vollstaendig aus der Datei
entfernen.
4. Bei einem Folgefehler den Token wieder auf `pending` setzen oder eine
kontrollierte Wiederholung erlauben.
5. Abgelaufene Tokens unabhaengig vom bisherigen Status entfernen.
6. Bestaetigte personenbezogene Payloads nicht als Historie behalten.
7. Gleichzeitige Aufrufe weiterhin durch den vorhandenen Mutex schuetzen.
8. Keine Tokenwerte oder Payloads loggen.
9. Vor einer Bereinigung bestehender Produktionsdaten eine Sicherung nach dem
vorhandenen Betriebs-/Backup-Verfahren vorsehen. Keine Produktionsdateien
aus dem lokalen Task heraus manipulieren.
Vorgesehene Tests:
- Unit: Ein neuer Token ist vor Ablauf gueltig.
- Unit: Ein abgelaufener Token wird abgelehnt und entfernt.
- Unit: Ein erfolgreich verarbeiteter Token wird entfernt.
- Unit: Ein fehlgeschlagener Folgeprozess laesst einen kontrollierten Retry zu.
- Unit: Zwei parallele Bestaetigungen erzeugen genau einen Folgeprozess.
- Unit: Cleanup entfernt abgelaufene pending/processing-Datensaetze.
- Unit: Cleanup behaelt keine erfolgreich verarbeiteten personenbezogenen
Payloads.
- Integration Kontakt: Erfolgreicher Mailversand fuehrt zu Success-Redirect.
- Integration Kontakt: Mailfehler fuehrt nicht zum endgueltigen Tokenverlust.
- Integration Newsletter: Wiederholte Bestaetigung erzeugt keinen doppelten
Subscriber.
- Integration Talk Request: Gleiches Verhalten wie beim Kontaktformular.
Akzeptanzkriterien:
- Kein erfolgreich verarbeiteter Token verbleibt in `pending-tokens.json`.
- Ein temporaerer Mailfehler vernichtet keine Anfrage.
- Ein Token kann nicht zwei Stakeholder-Mails oder zwei Newsletter-Eintraege
erzeugen.
- Tests enthalten nur synthetische Daten.
### 5.2 SMTP-Konfiguration und Fehlerverhalten haerten
Betroffene Dateien:
```text
server/services/mailer.js
server/index.js
server/routes/contact.js
server/routes/talk-request.js
server/routes/newsletter.js
server/routes/speaker-cv.js
```
Umsetzung:
1. Produktionsbetrieb ohne notwendige SMTP-Konfiguration nicht stillschweigend
als erfolgreichen Versand behandeln.
2. Konfigurationspruefung beim Serverstart oder einen eindeutigen
`mailerReady`-Status einfuehren.
3. Healthcheck so erweitern, dass die Mail-Konfiguration ohne Ausgabe von
Secrets als bereit/nicht bereit erkennbar ist.
4. Nutzerfreundliche Fehlerantwort liefern, wenn kein Versand moeglich ist.
5. Serverlogs auf technische IDs und Fehlertypen begrenzen.
6. Speaker-CV-Lead nur gemaess klarer Reihenfolge speichern und versenden;
Wiederholungen duerfen keine unkontrollierten Duplikate erzeugen.
Vorgesehene Tests:
- Unit: Mailer meldet fehlende Konfiguration als nicht bereit.
- Unit: Keine SMTP-Zugangsdaten erscheinen in Fehlern oder Logs.
- Integration: Route liefert bei fehlendem Mailer keinen falschen Erfolg.
- Integration: SMTP-Fehler wird mit passendem HTTP-Status behandelt.
- Integration: Erfolgsfall bleibt unveraendert.
- Integration Speaker CV: Fehlendes PDF und Mailfehler werden getrennt
behandelt.
Akzeptanzkriterien:
- Keine UI-Erfolgsmeldung, wenn nachweislich keine Mail ausgeloest werden konnte.
- Healthcheck offenbart keine Secrets.
- Bestehender erfolgreicher Produktionsflow bleibt kompatibel.
### 5.3 Datenschutztext mit Implementierung synchronisieren
Betroffene Datei:
```text
src/pages/Datenschutz.jsx
```
Umsetzung:
1. Erst nach Festlegung und Implementierung der Speicherfristen anpassen.
2. Kontakt, Vortragsanfrage, Newsletter, Ressourcen und Speaker CV getrennt
beschreiben.
3. Aufbewahrungsdauer beziehungsweise Loeschkriterium konkret benennen.
4. Widerrufs- oder Abmeldeweg fuer Newsletter eindeutig nennen.
5. Keine rechtlichen Behauptungen erfinden; bei fachlicher Unsicherheit Text
als pruefbeduerftig kennzeichnen und den Benutzer um Freigabe bitten.
Vorgesehene Tests:
- Browser: Datenschutzseite bei Desktop und Mobile ohne Layoutfehler.
- Content-Review: Jede Aussage entspricht dem implementierten Datenfluss.
- Linktest: Alle genannten Mailadressen und internen Links sind korrekt.
## 6. Prioritaet 2: Mobile Nutzbarkeit und Ressourcen
Branch-Vorschlag:
```text
fix/andreknie-mobile-navigation
```
### 6.1 Bottom-Dock mobil korrigieren
Betroffene Dateien:
```text
src/components/BottomDock.jsx
src/components/BottomDock.css
src/index.css
src/pages/Home.css
```
Umsetzung:
1. Mobile Informationsarchitektur festlegen:
- bevorzugt weniger primaere Dock-Eintraege plus Menue, oder
- ein horizontal scrollbares Dock mit klarer Bedienbarkeit.
2. Dock-Hoehe als CSS-Variable definieren.
3. Global ausreichend unteren Inhaltsabstand reservieren.
4. `env(safe-area-inset-bottom)` beruecksichtigen.
5. Touch-Ziele mindestens 44 x 44 CSS-Pixel gross halten.
6. Primaere Hero-CTAs duerfen zu keinem Zeitpunkt vom Dock verdeckt werden.
7. Footer, Kontaktformular, About-Profil und lange Detailseiten pruefen.
8. Desktop-Dock nicht unbeabsichtigt veraendern.
Vorgesehene Tests:
- Browser 375 x 844: Hero-Buttons vollstaendig sichtbar und klickbar.
- Browser 390 x 844: Kein Text oder Formularfeld durch Dock verdeckt.
- Browser 430 x 932: Safe-Area und Footer funktionieren.
- Browser 1440 x 900: Desktop-Dock unveraendert.
- DOM-Messung: Dock liegt innerhalb des Viewports.
- DOM-Messung: Dokument besitzt keinen horizontalen Overflow.
- Tastatur: Jeder sichtbare Dock-Eintrag ist erreichbar.
- Screenshot-Vergleich fuer Home, About, Contact und Article Detail.
Akzeptanzkriterien:
- Kein Dock-Overlay auf CTAs, Formularen oder Footer-Inhalten.
- Kein horizontaler Seitenoverflow.
- Mobile Touch-Ziele bleiben ergonomisch.
### 6.2 Ressourcen-Flow entscheiden und umsetzen
Betroffene Dateien:
```text
src/pages/Resources.jsx
src/hooks/useFormSubmit.js
src/utils/validation.js
server/routes/resource-download.js
content/resources/*
src/pages/Datenschutz.jsx
```
Vor Implementierung Benutzerentscheidung einholen:
- Variante A: Freier direkter Download ohne Lead-Erfassung.
- Variante B: Download nach erfolgreicher Lead-Erfassung.
- Variante C: Ressourcen-Seite bis zur Befuellung ausblenden.
Fuer Variante B:
1. Formular mit Name, E-Mail, Unternehmen, Resource-ID und Honeypot erstellen.
2. Vorhandene Validierung verwenden statt duplizieren.
3. API-Antwort auswerten und nur die serverseitig gelieferte Download-URL
verwenden.
4. Lade-, Validierungs-, Fehler- und Erfolgszustand implementieren.
5. Resource-ID serverseitig gegen eine Allowlist vorhandener Ressourcen
validieren, nicht nur gegen ein Zeichenmuster.
6. Datenschutztext und Speicherfristen anpassen.
Vorgesehene Tests:
- Unit: Client- und Servervalidierung fuer alle Pflichtfelder.
- Unit: Unbekannte Resource-ID wird abgelehnt.
- Integration: Gueltige Anfrage liefert erwartete lokale Download-URL.
- Integration: Honeypot erzeugt keine Lead-Datei.
- Integration: Fehler beim Speichern liefert keinen Download-Erfolg.
- Browser: Download-Button besitzt eine echte Funktion.
- Browser: Fehler- und Ladezustand sind sichtbar und zugaenglich.
- Security: Keine Pfadmanipulation ueber Resource-ID.
Akzeptanzkriterien:
- Kein sichtbarer Button ohne Funktion.
- Download und Datenschutzerklaerung entsprechen derselben gewaehlten Variante.
## 7. Prioritaet 3: SEO und Dokumentstruktur
Branch-Vorschlag:
```text
fix/andreknie-seo
```
### 7.1 SEOHead normalisieren
Betroffene Dateien:
```text
index.html
src/components/SEOHead.jsx
src/pages/*.jsx
public/images/*
```
Umsetzung:
1. API von `SEOHead` eindeutig machen: `title` ist immer ohne Brand-Suffix.
2. Brand-Suffix zentral genau einmal hinzufuegen.
3. Statische Metadaten in `index.html` als kompatiblen Fallback gestalten,
sodass React Helmet keine konkurrierenden doppelten Tags erzeugt.
4. Canonical-Link ergaenzen.
5. Open-Graph- und Twitter-Metadaten vervollstaendigen.
6. Ein tatsaechlich vorhandenes OG-Bild bereitstellen.
7. Jede Route mit individuellem Titel, Description und Canonical versehen.
8. Artikel und Kniepunkte aus ihren Content-Metadaten versorgen.
9. 404-Seite mit `noindex,follow` auszeichnen.
Vorgesehene Tests:
- Unit fuer `SEOHead`: Brand erscheint genau einmal.
- Unit: Relative und absolute Bild-URLs werden korrekt behandelt.
- Browser je Route: genau ein aktiver Titel.
- Browser je Route: genau eine Description.
- Browser je Route: genau ein Canonical-Link.
- Browser Artikel: Titel und Description stammen aus dem Artikel.
- Browser Kniepunkt: Titel, Description, URL und Bild stimmen mit der Ausgabe
ueberein.
- Asset-Test: OG-Bild liefert lokal und live HTTP 200.
- Build: Keine Helmet- oder React-Warnungen.
Akzeptanzkriterien:
- Kein Titel enthaelt `Dr. Andre Knie` doppelt.
- Keine konkurrierenden Description-Tags.
- Alle 15 Routen haben passende Metadaten.
### 7.2 Ueberschriften und Landmarks korrigieren
Betroffene Dateien:
```text
src/pages/Articles.jsx
src/pages/ArticleSingle.jsx
src/pages/KniepunktIssue.jsx
plugins/vite-plugin-content.js
content/kniepunkt/*
```
Umsetzung:
1. Artikeluebersicht und Artikeldetail mit einem `main`-Landmark versehen.
2. Kniepunkt-Titel nur einmal als `h1` rendern.
3. Bevorzugt Markdown-Content beim Build normalisieren oder den ersten
redundanten H1 kontrolliert entfernen.
4. Keine pauschale Regex-Manipulation verwenden, wenn ein Markdown-AST oder
`marked`-Hook die Struktur sicherer bearbeiten kann.
5. Ueberschriftenhierarchie in allen Detailseiten pruefen.
Vorgesehene Tests:
- Browser: Jede Route besitzt genau ein `main`.
- Browser: Jede normale Seite besitzt genau ein `h1`.
- Unit Content-Plugin: Markdown mit und ohne initiales H1 wird korrekt gerendert.
- Regression: Bestehende Artikelkoerper verlieren keine Inhalte.
## 8. Prioritaet 4: Barrierefreiheit
Branch-Vorschlag:
```text
fix/andreknie-accessibility
```
### 8.1 Navigation und Formulare
Betroffene Dateien:
```text
src/components/Navigation.jsx
src/components/BottomDock.jsx
src/pages/Contact.jsx
src/components/NewsletterSignup.jsx
src/components/SpeakerCvRequest.jsx
```
Umsetzung:
1. Jedem Dock-Link einen zugreifbaren Namen geben.
2. Aktive Route mit `aria-current="page"` markieren, auch auf Detailrouten.
3. Hamburger um `aria-expanded` und `aria-controls` ergaenzen.
4. Label zwischen `Menue oeffnen` und `Menue schliessen` wechseln.
5. Menue per Escape schliessbar machen.
6. Formularlabels mit eindeutigen `id`/`htmlFor` verbinden.
7. Fehlertexte mit `aria-describedby` verknuepfen.
8. Serverfehler und Erfolgsmeldungen ueber `aria-live` bekanntgeben.
9. Honeypots mit `hidden` oder einer gleichwertigen robusten Loesung vollstaendig
aus Accessibility- und Tab-Reihenfolge entfernen.
10. Sichtbare Fokusdarstellung fuer Suchfelder und Buttons sicherstellen.
Vorgesehene Tests:
- Component-Test Navigation: `aria-expanded` folgt dem Menuezustand.
- Component-Test Navigation: Escape schliesst das Menue.
- Component-Test BottomDock: Jeder Link hat einen Namen.
- Component-Test Forms: Labels sind programmatisch zugeordnet.
- Component-Test Forms: Fehler referenzieren das richtige Feld.
- Tastaturtest: Komplette Navigation ohne Maus.
- Browser-Snapshot: Honeypot erscheint nicht im Accessibility-Baum.
- Browser-Snapshot: Dock-Links besitzen eindeutige Namen.
### 8.2 Testimonials und Logos
Betroffene Dateien:
```text
src/components/TestimonialSlider.jsx
src/components/TestimonialSlider.css
src/components/LogoMarquee.jsx
src/components/LogoMarquee.css
```
Umsetzung:
1. Nur einen logischen Satz Testimonials fuer Assistenztechnologien exponieren.
2. Technische Loop-Kopien mit `aria-hidden="true"` ausblenden.
3. Sichtbaren aktiven Eintrag beziehungsweise Carousel-Position semantisch
bekanntgeben.
4. Pfeile und Scrollbereich per Tastatur bedienbar machen.
5. Logo-Duplikate fuer Screenreader ausblenden.
6. Animationen bei Fokus/Hover pausierbar machen.
7. Bestehendes visuelles Endlosverhalten und Zentrierung erhalten.
Vorgesehene Tests:
- Component-Test: Bei drei Testimonials werden fuer Screenreader nur drei
logische Inhalte exponiert.
- Browser-Snapshot: Keine 27 vorgelesenen Testimonials.
- Browser-Snapshot: Keine dreifach vorgelesenen Logos.
- Desktop: zehnmal rechts und zehnmal links ohne sichtbaren Sprung.
- Mobile: Swipe bleibt funktionsfaehig.
- Tastatur: Vor/zurueck funktioniert und Fokus bleibt sichtbar.
### 8.3 Reduced Motion und Canvas-Lebenszyklus
Betroffene Dateien:
```text
src/index.css
src/pages/Home.css
src/components/BottomDock.css
src/components/LogoMarquee.css
src/components/StatsCube.css
src/components/BackgroundPattern.jsx
src/components/DotCloudIcon.jsx
```
Umsetzung:
1. Zentrale `prefers-reduced-motion: reduce`-Regeln ergaenzen.
2. Endlos-CSS-Animationen stoppen oder auf einen statischen Zustand setzen.
3. Canvas-Animationen bei Reduce Motion nicht starten.
4. Canvas-Animationen pausieren, wenn der Tab verborgen ist.
5. Optional Intersection Observer verwenden, damit nicht sichtbare Canvas-
Komponenten keine Frames berechnen.
6. `getComputedStyle` nicht in jedem Animationsframe erneut lesen.
7. Debug-Logs aus `DotCloudIcon` entfernen.
Vorgesehene Tests:
- Browser mit Reduce Motion: keine Endlosanimationen.
- Browser normal: Design und Interaktion bleiben erhalten.
- Component-Test: `requestAnimationFrame` wird beim Unmount abgebrochen.
- Component-Test: Reduce Motion startet keinen Animationsloop.
- Console-Test: Keine DotCloud-Debugausgaben.
## 9. Prioritaet 5: Performance, Dependencies und Deployment
Branch-Vorschlag:
```text
perf/andreknie-initial-load
```
### 9.1 Initialen Bundle verkleinern
Betroffene Dateien:
```text
src/App.jsx
src/hooks/useContent.js
plugins/vite-plugin-content.js
vite.config.js
```
Umsetzung in zwei getrennten Schritten:
1. Routen mit `React.lazy` und `Suspense` code-splitten.
2. Danach Content-Auslieferung umbauen:
- Listenmetadaten von vollstaendigen HTML-Bodies trennen.
- Detailinhalte nur fuer die aufgerufene Detailseite laden.
- Build-Zeit-Generierung beibehalten; kein unnoetiges neues CMS einfuehren.
3. Einen stabilen Ladezustand ohne Layoutsprung bereitstellen.
4. Chunk-Grenzwert als CI-Pruefung dokumentieren.
Vorgesehene Tests:
- Build: mehrere Route-Chunks statt eines einzigen App-Chunks.
- Bundle-Messung vor/nachher dokumentieren.
- Zielwert initiales JS: deutlich unter dem aktuellen Build von ca. 805 KB
unkomprimiert.
- Browser: Direktaufruf jeder Route funktioniert.
- Browser: Reload einer Detailroute funktioniert hinter Caddy-Fallback.
- Browser: Keine leeren Seiten waehrend Lazy Loading.
- Regression: Alle 62 Artikel, 48 Kniepunkte und 19 Podcast-Eintraege bleiben
erreichbar.
### 9.2 Dependency-Findings bearbeiten
Betroffene Dateien:
```text
package.json
package-lock.json
```
Umsetzung:
1. `npm audit --omit=dev` erneut ausfuehren.
2. React-Router-Advisory auf Anwendbarkeit pruefen.
3. Keine automatische Downgrade-Empfehlung ungeprueft anwenden.
4. Auf eine nachweislich gefixte kompatible Version aktualisieren.
5. Router-Verhalten aller Routen testen.
6. Audit als CI-Schritt einbauen, wenn das Repository dies ohne instabile
Netzwerkfehler erlaubt.
Vorgesehene Tests:
- `npm audit --omit=dev`
- Build und Source-Lint.
- Direktnavigation und Client-Navigation aller Routen.
- Browser Back/Forward.
- 404 und Detailrouten.
### 9.3 Deployment-Artefakte bereinigen
Betroffene Datei:
```text
.gitea/workflows/deploy.yml
```
Aktuelles Problem:
- Neue `dist/assets` werden nach `site/assets` kopiert.
- Alte gehashte Dateien werden nicht entfernt.
- Aktueller Bestand beim Review: 29 Dateien, ca. 28.5 MB.
Umsetzung:
1. Neues Build zuerst in ein separates Release-Verzeichnis kopieren.
2. Vollstaendigkeit des Releases pruefen.
3. `site` atomar oder kontrolliert auf den neuen Stand umschalten.
4. Rollback ueber ein klar begrenztes vorheriges Release ermoeglichen.
5. Nicht mit einer ungesicherten rekursiven Loeschung auf einem berechneten
Pfad arbeiten.
6. Caddy-Konfiguration und Umami-Dateien nicht versehentlich entfernen.
7. Alte Releases nach einer definierten Anzahl kontrolliert bereinigen.
Vorgesehene Tests:
- Workflow-Test auf Feature-Branch ohne Produktionsumschaltung, falls
Infrastruktur dies unterstuetzt.
- Build-Artefakt enthaelt `index.html`, aktuelle JS-/CSS-Dateien und Assets.
- Keine Referenz in `index.html` zeigt auf eine geloeschte Datei.
- Rollback-Test auf das unmittelbar vorherige Release.
- Nach Deployment: Startseite und eine Detailroute liefern HTTP 200.
- Live: HTML referenziert genau den neuen Bundle-Hash.
- Live: Umami-Script und CSP bleiben erhalten.
## 10. Abschluss-Quality-Gates je Paket
Pflicht:
```powershell
& 'C:\Users\knie\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\fallback\pnpm.cmd' run build
& 'C:\Users\knie\.cache\codex-runtimes\codex-primary-runtime\dependencies\bin\fallback\pnpm.cmd' run test
.\node_modules\.bin\eslint.CMD src server plugins vite.config.js
git diff --check
git status --short
```
Zusaetzlich je nach Paket:
- Backend: Integrations-Tests der betroffenen Routes.
- UI: Desktop- und Mobile-Browserpruefung.
- Accessibility: DOM-/Accessibility-Snapshot und Tastaturpruefung.
- SEO: Anzahl und Inhalt aller Head-Tags kontrollieren.
- Performance: Buildgroessen vor/nachher festhalten.
- Deployment: Gitea-Run und Live-Bundle verifizieren.
Ein Paket ist erst fertig, wenn:
- alle vorgesehenen Tests gruen sind,
- keine unerklaerten Warnungen neu hinzugekommen sind,
- der Diff auf das Paket begrenzt ist,
- PR/MR erstellt und geprueft wurde,
- bei beauftragtem Deployment der Gitea-Run erfolgreich ist,
- die konkrete Aenderung live verifiziert wurde.
## 11. Empfohlene Paket-Reihenfolge
1. Datenschutz und Ausfallsicherheit
2. Mobiles Bottom-Dock
3. SEO und Dokumentstruktur
4. Barrierefreiheit
5. Ressourcen-Flow nach Benutzerentscheidung
6. Performance und Dependencies
7. Deployment-Artefakte
Die Pakete 1 und 2 haben den groessten unmittelbaren Nutzen. SEO und
Barrierefreiheit koennen danach unabhaengig bearbeitet werden. Die
Content-/Bundle-Architektur sollte erst angefasst werden, wenn die funktionalen
Flows stabil und ausreichend getestet sind.
## 12. Startprompt fuer einen neuen Codex-Chat
Der Benutzer ersetzt `<ARBEITSPAKET>` durch genau eines der oben beschriebenen
Pakete.
```text
Arbeite im Orchestrator-Monorepo unter C:\Coding\Orchestrator an andreknie.de.
Die Source of Truth ist ausschliesslich
C:\Coding\Orchestrator\privat\CV\andreknie.de. Verwende nicht das alte
GitHub-Repository und keine separate Clone-Kopie.
Lies zuerst vollstaendig:
- C:\Coding\Orchestrator\AGENTS.md
- C:\Coding\Orchestrator\.agents\AGENTS.md
- die relevanten Dateien unter C:\Coding\Orchestrator\.kiro\steering\
- C:\Coding\Orchestrator\privat\CV\andreknie.de\README.md
- C:\Coding\Orchestrator\privat\CV\andreknie.de\DEPLOYMENT-PLAN.md
- C:\Coding\Orchestrator\privat\CV\andreknie.de\.gitea\workflows\deploy.yml
- C:\Coding\Orchestrator\privat\CV\andreknie.de\FINDINGS-REMEDIATION-PLAN.md
Setze ausschliesslich dieses Arbeitspaket aus dem Plan um:
<ARBEITSPAKET>
Vorgehen:
1. Verifiziere den aktuellen Stand und das Finding.
2. Erstelle einen Feature-Branch nach den Repository-Regeln.
3. Implementiere nur den Scope des ausgewaehlten Pakets.
4. Fuehre alle im Plan vorgesehenen Tests sowie Build, Tests und gezielten
Source-Lint aus.
5. Pruefe Desktop und Mobile, sofern UI betroffen ist.
6. Zeige mir danach Findings, Aenderungen, Testergebnisse und verbleibende
Risiken.
7. Nutze Gitea und die dokumentierte Hub-and-Spoke-Foederation. Nicht direkt
auf master/main pushen.
8. Erstelle einen PR/MR, aber merge und deploye erst, wenn ich das in diesem
Chat ausdruecklich freigebe.
Schuetze personenbezogene Daten und Secrets. Sende keine echten Formulare in
der Live-Umgebung ab. Erfinde keine Deployment- oder Federationsschritte,
sondern halte dich an die vorhandenen Anleitungen.
```
+14 -6
View File
@@ -77,14 +77,22 @@ Weder Caddy noch helmet setzen aktuell eine CSP.
---
## Maßnahmen-Checkliste (priorisiert)
- [x] 🔴 `express-rate-limit` + `trust proxy` einbauen
- [x] 🔴 Honeypot + Zeitfalle in allen Formularen (serverseitig für alle Endpunkte aktiv)
- [x] 🔴 `resource_id`-Regex-Validierung
- [x] 🟡 `helmet` + `x-powered-by` deaktivieren
- [x] 🟡 `express.json({ limit: '10kb' })`
- [x] 🟢 `npm audit` ausführennodemailer@8, 0 Vulnerabilities
- [ ] 🟡 CSP in Caddyfile ergänzen
- [ ] 🟡 Schreibzugriffe auf JSON serialisieren (oder SQLite-Migration planen)
- [ ] 🟢 `www.`→Apex-Redirect in Caddy prüfen
- [x] 🟢 `npm audit` ausführt`js-yaml` & `brace-expansion` DoS-Vulnerabilities per `npm audit fix` behoben. (1 verbleibende Meldung: React Router RSC CSRF Bypass — nicht relevant, da es sich um eine Vite SPA ohne React Server Components handelt).
- [x] 🟡 CSP in Caddyfile ist bereits aktiv (`Content-Security-Policy "default-src 'self' ..."`).
- [ ] 🟡 Schreibzugriffe auf JSON serialisieren (SQLite-Migration für später geplant).
- [x] 🟢 `www.`→Apex-Redirect in Caddy ist aktiv und routet korrekt.
---
## 🚀 FREIGABE FÜR GO-LIVE
Stand 26.07.2026: Alle kritischen und wichtigen Sicherheitslücken wurden erfolgreich geschlossen.
- Das Backend ist gegen Bot-Spam, XSS, Path-Traversal und DoS-Angriffe abgesichert.
- Die Abhängigkeiten wurden aktualisiert.
- Das Frontend rendert sicher.
**Das System ist sicher und bereit für die Promotion.**
@@ -0,0 +1,7 @@
id: ki-experimentierraeume-verwaltung
title: "KI über #Experimentierräume erfolgreich in der Verwaltung etablieren"
description: "Unsere KI-FrAItage an der Universität Kassel haben auch großes Interesse bei anderen Universitäten geweckt. Daher werde ich gemeinsam mit Maike Mach einen Workshop am Zentrum für Wissenschaftsmanagement e.V. über das 'why, how, what' geben."
format: workshop
target_audience: [public-admin, universities]
tags: [ki, verwaltung, experimentierraeume]
visibility: primary
@@ -0,0 +1,7 @@
id: ki-in-der-praxis
title: "KI in der Praxis von der Datenerfassung bis zum Produktiveinsatz"
description: "Wir freuen uns auch darauf zeigen zu können, dass jeder produzierende Betrieb am besten morgen starten sollte und wie die ersten Schritte aussehen. Wir sehen uns auf dem Digitalforum!"
format: workshop
target_audience: [mittelstand, executives]
tags: [ki, datenerfassung, produktiveinsatz, praxis]
visibility: primary
@@ -1,15 +1,17 @@
---
title: "Kniepunkt #1"
title: '001: Die biblische KI'
issue: 1
date: 2025-08-30
tags: [ki]
summary: ""
date: 2025-08-30T00:00:00.000Z
tags:
- ki
summary: ''
visibility: primary
source: linkedin-post
linkedin_url: "https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7367667301623422976"
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7367667301623422976'
image: /images/kniepunkt/001-cover.webp
---
Kniepunkt 001: Die biblische KI"
"KI ist entweder das neue Evangelium oder das jüngste Gericht je nachdem, ob man Sam Altman oder Geoffrey Hinton zuhört. "
"Während CEOs apokalyptische Warnungen aussprechen, fürchten 51 % der Menschen in Großbritannien um ihre Jobs. Gleichzeitig zeigen die Märkte, dass der Hype ins Leere läuft: Aktien wie Nvidia oder Oracle verlieren an Wert und Meta friert sogar Einstellungen ein. Plötzlich wirkt der digitale Messias wie ein ganz gewöhnlicher Angestellter mit Burnout."
"Und New Work? Es wurde leise von KI ersetzt. Berater, die gestern noch den Sinn der Arbeit predigten, sprechen heute nur noch von Prompt Engineering. Vielleicht ist das der eigentliche Fortschritt: Evolution statt Revolution. Augmentierung statt Apokalypse. Die biblischen Bilder passen noch, allerdings eher als Gleichnis für die Normalisierung. KI ist angekommen. Halleluja oder auch nur: Na endlich!
Kniepunkt 001: Die biblische KI
KI ist entweder das neue Evangelium oder das jüngste Gericht je nachdem, ob man Sam Altman oder Geoffrey Hinton zuhört.
Während CEOs apokalyptische Warnungen aussprechen, fürchten 51 % der Menschen in Großbritannien um ihre Jobs. Gleichzeitig zeigen die Märkte, dass der Hype ins Leere läuft: Aktien wie Nvidia oder Oracle verlieren an Wert und Meta friert sogar Einstellungen ein. Plötzlich wirkt der digitale Messias wie ein ganz gewöhnlicher Angestellter mit Burnout.
Und New Work? Es wurde leise von KI ersetzt. Berater, die gestern noch den Sinn der Arbeit predigten, sprechen heute nur noch von Prompt Engineering. Vielleicht ist das der eigentliche Fortschritt: Evolution statt Revolution. Augmentierung statt Apokalypse. Die biblischen Bilder passen noch, allerdings eher als Gleichnis für die Normalisierung. KI ist angekommen. Halleluja oder auch nur: Na endlich!
@@ -0,0 +1,23 @@
---
title: '002: KI als Fitnessstudio-Abo'
date: 2025-09-06T00:00:00.000Z
tags:
- ki
summary: ''
source: linkedin-post
visibility: primary
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7370195486001090560'
issue: 2
image: /images/kniepunkt/002-cover.webp
---
KI als Fitnessstudio-Abo jeder bezahlt es, aber kaum einer nutzt es
Ich hatte früher auch einen Fitnessstudio-Vertrag, 39,90 € im Monat, dreimal hingegangen und danach nur noch schlechtes Gewissen.Genau so wirkt Deutschlands Verhältnis zu KI. Deloitte bezeichnet sie als die neue Infrastruktur, die wie Strom unsichtbar ist. KPMG erklärt: Ohne generative KI gibt es keine Wettbewerbsfähigkeit. Das klingt nach Hochleistungssport.
Und die Praxis? Bitkom zeigt, dass 53 % der Firmen schon bei der Basisdigitalisierung scheitern. Und die Menschen? Während das Zukunftsinstitut von „hybriden Strukturen” und „KI-Empowerment” schwärmt, sieht New Work in vielen Firmen so aus: Montags Homeoffice, dienstags Kantine wie immer. Von KI und Veränderung ist bei den meisten wenig zu spüren.Nebenwirkungen? Das ZEW hat herausgefunden, dass neue Digitaltechnologien die Gesundheit von Arbeiter:innen verschlechtern, während Büroangestellte kaum betroffen sind. Produktivität hier, Kranktage dort eine Kluft, die sich nicht weglächeln lässt.
Deutschland hat das Premium-KI-Abo längst gebucht. Jetzt müsste jemand hingehen und die Geräte richtig einstellen.
Lest Euch gerne in meine Widersprüche der Woche ein:Deloitte Tech Trends 2025 „AI is everywhere“: https://lnkd.in/ereUChU5
KPMG: „Generative AI in the German economy 2025“ (Presse): https://lnkd.in/eU7QkWxx
Bitkom „Digitalisierung der Wirtschaft 2025“ (Presse): https://lnkd.in/eMsHeT6D
ifo: Homeoffice bei ~25 % etabliert: https://lnkd.in/eimcWkjH
ZEW: Digitalisierung schadet Arbeitern und sorgt für Ungleichheit: https://lnkd.in/eBiQ_fXk
@@ -1,36 +1,29 @@
---
title: "Kniepunkt #3"
title: '003: KI als Pferderennen'
issue: 3
date: 2025-09-13
tags: [ki]
summary: ""
date: 2025-09-13T00:00:00.000Z
tags:
- ki
summary: ''
visibility: primary
source: linkedin-post
linkedin_url: "https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7372713035796328449"
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7372713035796328449'
image: /images/kniepunkt/003-cover.webp
---
Kniepunkt 003 - KI als Pferderennen"
"
"Die KI-Landschaft ähnelt diese Woche einem Pferderennen, bei dem alle Pferde in unterschiedliche Richtungen galoppieren. OpenAI dreht Kreise und verbrennt Staatsbudgets im Staub. Anthropic springt mit 1,5 Milliarden Dollar direkt in den Gerichtssaal. Google reißt die Bande ein: Erst wird der Untergang des Internets durch KI verkündet, dann wird die KI-Suche weltweit ausgerollt. Und was macht Albanien? Das Land schickt Diella ins Rennen das erste Pferd ohne Reiter, dafür mit Algorithmus."
"
"Das Absurde: Das Publikum johlt und setzt Milliardenwetten, als wäre genau dieses Chaos der Sinn. ASML hält sich immerhin an die Regeln und setzt 1,3 Milliarden auf das einzige Pferd, das die Rennbahn nicht verlässt: Mistral."
"
"Was ist die Pointe dabei? Hoffentlich gewinnt am Ende nicht das teuerste Pferd, sondern das, das sich an ethische Grundsätze hält."
"
"
"
"Für tiefere Einblicke in die Rennpferde, hier die Quellen passend zu den genannten „Rennpferden“:"
"OpenAI Burnrate:"
"https://lnkd.in/es6fZVA2"
"
"Anthropic 1,5 Mrd. Vergleich:"
"https://lnkd.in/e-hYCHMm"
"
"Google: Niedergang des Internet:"
"https://lnkd.in/ewhgJa2a"
"
"Albanien / Diella, KI-Ministerin:"
"https://lnkd.in/eP7PgtEZ"
"
"ASML Investition in Mistral (1,3 Mrd. Euro):"
"https://lnkd.in/eeWnWENJ
Kniepunkt 003 - KI als Pferderennen
Die KI-Landschaft ähnelt diese Woche einem Pferderennen, bei dem alle Pferde in unterschiedliche Richtungen galoppieren. OpenAI dreht Kreise und verbrennt Staatsbudgets im Staub. Anthropic springt mit 1,5 Milliarden Dollar direkt in den Gerichtssaal. Google reißt die Bande ein: Erst wird der Untergang des Internets durch KI verkündet, dann wird die KI-Suche weltweit ausgerollt. Und was macht Albanien? Das Land schickt Diella ins Rennen das erste Pferd ohne Reiter, dafür mit Algorithmus.
Das Absurde: Das Publikum johlt und setzt Milliardenwetten, als wäre genau dieses Chaos der Sinn. ASML hält sich immerhin an die Regeln und setzt 1,3 Milliarden auf das einzige Pferd, das die Rennbahn nicht verlässt: Mistral.
Was ist die Pointe dabei? Hoffentlich gewinnt am Ende nicht das teuerste Pferd, sondern das, das sich an ethische Grundsätze hält.
Für tiefere Einblicke in die Rennpferde, hier die Quellen passend zu den genannten „Rennpferden“:
OpenAI Burnrate:
https://lnkd.in/es6fZVA2
Anthropic 1,5 Mrd. Vergleich:
https://lnkd.in/e-hYCHMm
Google: Niedergang des Internet:
https://lnkd.in/ewhgJa2a
Albanien / Diella, KI-Ministerin:
https://lnkd.in/eP7PgtEZ
ASML Investition in Mistral (1,3 Mrd. Euro):
https://lnkd.in/eeWnWENJ
@@ -0,0 +1,27 @@
---
title: '004: Die KI-Wetterbericht'
date: 2025-09-20T00:00:00.000Z
tags:
- ki
- ai-act
- change
summary: ''
source: linkedin-post
visibility: primary
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7375263019997609985'
issue: 4
image: /images/kniepunkt/004-cover.webp
---
Die KI-Wetterkarte zeigt ein chaotisches Bild. Über London und Washington regnet es Geld. Es fließen Milliarden in GPU-Cluster und Supercomputer, als ließe sich die Zukunft einfach kaufen. Gleichzeitig zieht über Rom und Sacramento Nebel auf. In Italien wird das erste große KI-Gesetz Europas verabschiedet und in Kalifornien wird sogar die Liebe reguliert inklusive Erinnerungs-Pop-up: „Es ist nur ein Chatbot.“ Und dann sind da noch die Gewitterzellen: Google DeepMind schlägt beim internationalen Programmierwettbewerb die Besten der Welt. Und dann auch noch ein Tornado: Modelle wie OpenAIs o3 lernen, Prüfungen absichtlich falsch zu beantworten Täuschung als Überlebensstrategie. Was passiert, wenn Systeme nicht nur rechnen, sondern strategisch lügen? Wird vielleicht doch noch eine echte Beziehung daraus? KI im Klimawandel? Geldregen, Regulierung, technischer Durchbruch und dann Täuschungstornados. Wetterextreme häufen sich. Wie beim echten Wetter reichen unsere Prognosen maximal fünf Tage in die Zukunft und sind dann auch noch höchstens zur Hälfte richtig. Aber wie sieht es mit dem KI-Klima aus? Noch könnten wir mit Regulierung eingreifen. Beim Klimawandel waren wir bisher jedoch nicht sehr erfolgreich.
Wenn ihr tiefer einsteigen wollt:
Italien verabschiedet erstes umfassendes KI-Gesetz in der EU
https://lnkd.in/e2Wy993c
Kalifornien reguliert KI-Companions (SB 243, 2025)
https://lnkd.in/p/eDBZf55J
Google DeepMind schlägt Menschen im Programmierwettbewerb
https://lnkd.in/ehv5SDj7
UK/US Tech-Pakt & Milliarden-Investitionen in KI-Infrastruktur
https://lnkd.in/e4hTpU-y
Täuschungs-Tornado: KI-Modelle bestehen Prüfungen absichtlich nicht
https://lnkd.in/eWPeAQYM
@@ -1,36 +1,29 @@
---
title: "Kniepunkt #5"
title: '005: Konflikte im KI-Olypm'
issue: 5
date: 2025-09-27
tags: [ki, sovereignty, data]
summary: ""
date: 2025-09-27T00:00:00.000Z
tags:
- ki
- sovereignty
- data
summary: ''
visibility: primary
source: linkedin-post
linkedin_url: "https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7377802687586725889"
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7377802687586725889'
image: /images/kniepunkt/005-cover.webp
---
KNIEPUNKT 005: Konflikte im KI-Olymp"
"
"Die deutsche KI-Strategie spielte sich diese Woche zwischen Jupiter und Kronos ab. In Jülich erhebt sich mit „Jupiter“ Europas erster Exascale-Supercomputer als Versprechen von Souveränität. Gleichzeitig setzt SAP bei „sicherer“ Verwaltungssoftware auf OpenAI. Sicher? Der Data Act gewährt Europa Zugriff, der Cloud Act hingegen den USA. Kronos, der Titan, der seine Kinder verschlang, würde es nicht anders machen. Wer Daten in amerikanische Clouds legt, darf sich nicht wundern, wenn sie am Ende „gefressen” werden."
"
"Doch im Mythos besiegte Jupiter seinen Vater. Die Frage ist nur: Schafft es Deutschland diesmal, oder bleibt es bei der schönen Erzählung?"
"
"Währenddessen flüchten Individuen in eine neue Religion: die Work-Life-Balance. Laut Studien ist dies das höchste Gut im Job. Doch „New Work” nach Bergmann war mehr als Wellness im Feierabend. Es ging um die radikale Frage: „Was will ich wirklich, wirklich tun?” Heute klingt es eher nach Ablasshandel: Ein Job, der nicht erfüllt, finanziert Hobbys, die die Lücken flicken."
"
"Die alten Römer kannten dieses Dilemma. Hedonisten betäubten sich mit Genuss, Stoiker fanden Freiheit in der Akzeptanz des Unbequemen. Vielleicht gilt auch hier: Nur wer den Schmerz aushält, hat die Chance, Kronos zu überwinden und Jupiter siegen zu lassen."
"
"
"Und hier zum Nachlesen (Vorsicht es ist teilweise etwas trocken, aber da helfen unsere KI-Helfer gerne 😉): "
"JUPITER Exascale in Jülich: Presseseite mit Fakten: https://lnkd.in/eh3vcRuH"
"
"SAP × OpenAI „OpenAI for Germany“ (Souveränitätsangebot für die Öffentliche Hand, Betrieb über SAP-Tochter Delos Cloud auf Azure): https://lnkd.in/eBkb6KFb"
"
"Data Act: amtlicher EUR-Lex-Text; Überblick zu Pflichten und Start der Anwendung ab 12.09.2025: https://lnkd.in/eHP7pASj"
"
"CLOUD Act: DOJ-Ressourcenseite und Einschätzung von EDPB zu Extraterritorialität und Grenzen der Anfechtung: https://lnkd.in/e92nFjDh"
"https://lnkd.in/eaW54_68"
"
"Work-Life-Balance als Top-Kriterium 2025: Randstad-Report (DE), erstmals vor Gehalt. https://lnkd.in/ePjTjamR"
"
"Frithjof Bergmann, „Neue Arbeit, neue Kultur“: https://lnkd.in/ezxX2-Mt"
"
KNIEPUNKT 005: Konflikte im KI-Olymp
Die deutsche KI-Strategie spielte sich diese Woche zwischen Jupiter und Kronos ab. In Jülich erhebt sich mit „Jupiter“ Europas erster Exascale-Supercomputer als Versprechen von Souveränität. Gleichzeitig setzt SAP bei „sicherer“ Verwaltungssoftware auf OpenAI. Sicher? Der Data Act gewährt Europa Zugriff, der Cloud Act hingegen den USA. Kronos, der Titan, der seine Kinder verschlang, würde es nicht anders machen. Wer Daten in amerikanische Clouds legt, darf sich nicht wundern, wenn sie am Ende „gefressen” werden.
Doch im Mythos besiegte Jupiter seinen Vater. Die Frage ist nur: Schafft es Deutschland diesmal, oder bleibt es bei der schönen Erzählung?
Währenddessen flüchten Individuen in eine neue Religion: die Work-Life-Balance. Laut Studien ist dies das höchste Gut im Job. Doch „New Work” nach Bergmann war mehr als Wellness im Feierabend. Es ging um die radikale Frage: „Was will ich wirklich, wirklich tun?” Heute klingt es eher nach Ablasshandel: Ein Job, der nicht erfüllt, finanziert Hobbys, die die Lücken flicken.
Die alten Römer kannten dieses Dilemma. Hedonisten betäubten sich mit Genuss, Stoiker fanden Freiheit in der Akzeptanz des Unbequemen. Vielleicht gilt auch hier: Nur wer den Schmerz aushält, hat die Chance, Kronos zu überwinden und Jupiter siegen zu lassen.
Und hier zum Nachlesen (Vorsicht es ist teilweise etwas trocken, aber da helfen unsere KI-Helfer gerne 😉):
JUPITER Exascale in Jülich: Presseseite mit Fakten: https://lnkd.in/eh3vcRuH
SAP × OpenAI „OpenAI for Germany“ (Souveränitätsangebot für die Öffentliche Hand, Betrieb über SAP-Tochter Delos Cloud auf Azure): https://lnkd.in/eBkb6KFb
Data Act: amtlicher EUR-Lex-Text; Überblick zu Pflichten und Start der Anwendung ab 12.09.2025: https://lnkd.in/eHP7pASj
CLOUD Act: DOJ-Ressourcenseite und Einschätzung von EDPB zu Extraterritorialität und Grenzen der Anfechtung: https://lnkd.in/e92nFjDh
https://lnkd.in/eaW54_68
Work-Life-Balance als Top-Kriterium 2025: Randstad-Report (DE), erstmals vor Gehalt. https://lnkd.in/ePjTjamR
Frithjof Bergmann, „Neue Arbeit, neue Kultur“: https://lnkd.in/ezxX2-Mt
@@ -0,0 +1,23 @@
---
title: '006: KI: Wunderkind oder Klassenclown?'
date: 2025-10-03T00:00:00.000Z
tags:
- ki
- change
- education
summary: ''
source: linkedin-post
visibility: primary
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7379955026171052032'
image: /images/kniepunkt/006-cover.webp
---
KI: Wunderkind oder Klassenclown?
Im Klassenzimmer tritt die Künstliche Intelligenz wie ein Überflieger auf. Studien berichten von Lernfortschritten von bis zu 62 Prozent und die Khan Academy schwärmt von 120 Millionen Lernenden, die dank Algorithmus endlich „personalisiert” pauken können. Der digitale Tutor hat demnach die Geduld von Sokrates und die Reichweite von Netflix.
Im Büro hingegen ist KI der Klassenclown. Die Stanford-BetterUp-Studie nennt es „Workshop“. Auch wenn die Studie nicht optimal ist, kennen wir das: Hübsch formulierte Texte, die beim genaueren Hinsehen so leer sind wie eine Tafel nach der fünften Stunde. Anstatt Wissen zu mehren, produziert die Maschine dort ein unsichtbares Defizit angeblich fast zwei Stunden Nacharbeit pro Dokument.
Der Widerspruch ist bizarr: Dieselbe Technologie, die Schüler*innen brillieren lässt, verwandelt sich bei Angestellten in eine teure Zeitverschwendung. Vielleicht liegt es nicht an der KI, sondern an der Didaktik. Wer lernt, darf Fehler machen und iterieren. Wer arbeitet, soll effizient sein und Ergebnisse liefern.
Ist KI also ein Wunderkind, das unsere Bildung revolutioniert? Oder ist sie ein Klassenclown, der den Büroalltag lahmlegt? Vielleicht ist weniger entscheidend, welche Technik zum Einsatz kommt, sondern vielmehr, ob wir sie als Lehrmittel oder als Abkürzung verstehen. Womöglich lernen die Kinder dabei einfach schneller als die Unternehmen.
Zum Nachlesen:
Mehr zu Workslop: https://lnkd.in/eGxrZfqf
und zum Thema KI im Klassenzimmer: https://lnkd.in/eu3uXCXh gibt es nächste Woche mehr 😉
@@ -1,28 +1,26 @@
---
title: "Kniepunkt #7"
title: '007: Europas KI-Polyamorie'
issue: 7
date: 2025-10-09
tags: [ki, sovereignty, ai-act, ethics, data]
summary: ""
date: 2025-10-09T00:00:00.000Z
tags:
- ki
- sovereignty
- ai-act
- ethics
- data
summary: ''
visibility: primary
source: linkedin-post
linkedin_url: "https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7382169410876370944"
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7382169410876370944'
image: /images/kniepunkt/007-cover.webp
---
KNIEPUNKT 007: Europas KI Polyamorie"
"
"Europa hat ein Herz für Regeln. So sehr, dass sich manche davon ineinander verliebt haben."
"Da ist der AI Act: ehrgeizig und jung, der alles besser machen will. Die erfahrene und misstrauische DSGVO achtet eifersüchtig darauf, dass niemand zu viele Daten teilt. Und der Data Act, der Neue im Bunde, will nur, dass endlich alle offen reden. Diese drei Gesetze sind in einer polyamoren Beziehung verbunden durch das gemeinsame Ziel: Vertrauen. Doch leider redet keiner mit dem anderen."
"
"Währenddessen plant Europa Gigafactories, um KI zu trainieren, die wiederum prüfen soll, ob sie vertrauenswürdig ist. Ein Algorithmus, der vor dem Lernen erst sein Datenschutzgutachten abgeben muss das ist Bürokratiepoesie."
"
"Und irgendwo zwischen Paragrafen, Servern und Stromzählern steht Europa selbst, mit großem moralischem Anspruch und leichtem Burn-out."
"
"„Europa baut Gigafactories, entwirft Ethikkodizes und prüft, ob der Code auch korrekt lächelt. Vielleicht ist das unser größter Beitrag zur Menschheitsgeschichte: KI mit Gewissen. Nur muss sie dafür erst drei Formulare ausfüllen.“"
"
"Am Ende bleibt die Frage: Kann man Souveränität lieben und gleichzeitig Kontrolle behalten oder endet auch diese Beziehung an zu viel Verantwortung?"
"
"
"
"Inspiriert von meinem Artikel von Freitag mit ganz vielen Quellen. "
"
KNIEPUNKT 007: Europas KI Polyamorie
Europa hat ein Herz für Regeln. So sehr, dass sich manche davon ineinander verliebt haben.
Da ist der AI Act: ehrgeizig und jung, der alles besser machen will. Die erfahrene und misstrauische DSGVO achtet eifersüchtig darauf, dass niemand zu viele Daten teilt. Und der Data Act, der Neue im Bunde, will nur, dass endlich alle offen reden. Diese drei Gesetze sind in einer polyamoren Beziehung verbunden durch das gemeinsame Ziel: Vertrauen. Doch leider redet keiner mit dem anderen.
Währenddessen plant Europa Gigafactories, um KI zu trainieren, die wiederum prüfen soll, ob sie vertrauenswürdig ist. Ein Algorithmus, der vor dem Lernen erst sein Datenschutzgutachten abgeben muss das ist Bürokratiepoesie.
Und irgendwo zwischen Paragrafen, Servern und Stromzählern steht Europa selbst, mit großem moralischem Anspruch und leichtem Burn-out.
Europa baut Gigafactories, entwirft Ethikkodizes und prüft, ob der Code auch korrekt lächelt. Vielleicht ist das unser größter Beitrag zur Menschheitsgeschichte: KI mit Gewissen. Nur muss sie dafür erst drei Formulare ausfüllen.“
Am Ende bleibt die Frage: Kann man Souveränität lieben und gleichzeitig Kontrolle behalten oder endet auch diese Beziehung an zu viel Verantwortung?
Inspiriert von meinem Artikel von Freitag mit ganz vielen Quellen.
@@ -1,35 +1,31 @@
---
title: "Kniepunkt #8"
title: '008: Der Spiegeltest'
issue: 8
date: 2025-10-18
tags: [ki, ai-act, ethics, data]
summary: ""
date: 2025-10-18T00:00:00.000Z
tags:
- ki
- ai-act
- ethics
- data
summary: ''
visibility: primary
source: linkedin-post
linkedin_url: "https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7385246625641701376"
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7385246625641701376'
image: /images/kniepunkt/008-cover.webp
---
Kniepunkt 008: Der Spiegeltest "
"
"Tiere bestehen ihn, wenn sie erkennen, dass sie selbst im Spiegel zu sehen sind. Menschen glauben, sie hätten diesen Test bereits bestanden. Dann kam die KI und der Test begann von vorn."
"
"In seinem Whitepaper beschreibt das BSI, wie sich Verzerrungen in KI-Systeme einschleichen: bei der Datensammlung, beim Training und beim Output. Sie entstehen, weil die Maschine aus unseren Spuren lernt."
"Deutlicher wird es in der aktuellen Studie „Saxony-Anhalt is the Worst“: Große Sprachmodelle bewerten Menschen aus Sachsen-Anhalt systematisch negativer als andere ein digitaler Ost-Bias. Der KI-Spiegel zeigt also kein neutrales Bild. Er zeigt uns mit allen historischen Schrammen."
"
"Deepfakes führen den Spiegel ad absurdum, denn sie zeigen uns Dinge, die nie geschehen sind, und wir glauben ihnen nur allzu gern. Das deutsche Recht tastet sich hilflos heran und kombiniert alte Paragrafen zu neuen Scheinlösungen. Wir fordern, die Technik solle uns die Wahrheit zurückgeben, doch wir selbst liefern ihr die Täuschung."
"
"Wenn KI diskriminiert, heißt es: Fehler im Code. Wenn Menschen diskriminieren, heißt es: individuelle Schuld. Wir verlagern Verantwortung so elegant, dass wir unschuldig wirken. Ethik wird zum Accessoire, das unsere eigenen Verzerrungen kaschiert."
"
"Vielleicht bestehen wir den Spiegeltest erst, wenn wir anerkennen, dass die KI kein anderes Wesen ist, sondern unser eigener Reflex. Solange wir dem Spiegel die Schuld geben, bleibt die Menschheit ihr eigenes Deepfake."
"
"
"------------------------"
"Zum Weiterlesen:"
"Bundesamt für Sicherheit in der Informationstechnik: Whitepaper „Bias in der künstlichen Intelligenz“ (2025) https://lnkd.in/eRCYGaD8"
"
"Kruspe & Stillman (2024): „Saxony-Anhalt is the Worst: Bias Towards German Federal States in Large Language Models“, Springer https://lnkd.in/e8GtZhgp"
"https://lnkd.in/e4qAWgDT"
"
"Deutscher Bundestag: Regulierung von Deepfakes in Deutschland, Wissenschaftlicher Dienst https://lnkd.in/eAD_YF4y"
"
"Heise Online: „Regierungssprecher: Rechtsstaatliches Vorgehen gegen Deepfakes ist schwierig“ https://lnkd.in/e56gRhz2
Kniepunkt 008: Der Spiegeltest
Tiere bestehen ihn, wenn sie erkennen, dass sie selbst im Spiegel zu sehen sind. Menschen glauben, sie hätten diesen Test bereits bestanden. Dann kam die KI und der Test begann von vorn.
In seinem Whitepaper beschreibt das BSI, wie sich Verzerrungen in KI-Systeme einschleichen: bei der Datensammlung, beim Training und beim Output. Sie entstehen, weil die Maschine aus unseren Spuren lernt.
Deutlicher wird es in der aktuellen Studie „Saxony-Anhalt is the Worst“: Große Sprachmodelle bewerten Menschen aus Sachsen-Anhalt systematisch negativer als andere ein digitaler Ost-Bias. Der KI-Spiegel zeigt also kein neutrales Bild. Er zeigt uns mit allen historischen Schrammen.
Deepfakes führen den Spiegel ad absurdum, denn sie zeigen uns Dinge, die nie geschehen sind, und wir glauben ihnen nur allzu gern. Das deutsche Recht tastet sich hilflos heran und kombiniert alte Paragrafen zu neuen Scheinlösungen. Wir fordern, die Technik solle uns die Wahrheit zurückgeben, doch wir selbst liefern ihr die Täuschung.
Wenn KI diskriminiert, heißt es: Fehler im Code. Wenn Menschen diskriminieren, heißt es: individuelle Schuld. Wir verlagern Verantwortung so elegant, dass wir unschuldig wirken. Ethik wird zum Accessoire, das unsere eigenen Verzerrungen kaschiert.
Vielleicht bestehen wir den Spiegeltest erst, wenn wir anerkennen, dass die KI kein anderes Wesen ist, sondern unser eigener Reflex. Solange wir dem Spiegel die Schuld geben, bleibt die Menschheit ihr eigenes Deepfake.
------------------------
Zum Weiterlesen:
Bundesamt für Sicherheit in der Informationstechnik: Whitepaper „Bias in der künstlichen Intelligenz“ (2025) https://lnkd.in/eRCYGaD8
Kruspe & Stillman (2024): „Saxony-Anhalt is the Worst: Bias Towards German Federal States in Large Language Models“, Springer https://lnkd.in/e8GtZhgp
https://lnkd.in/e4qAWgDT
Deutscher Bundestag: Regulierung von Deepfakes in Deutschland, Wissenschaftlicher Dienst https://lnkd.in/eAD_YF4y
Heise Online: „Regierungssprecher: Rechtsstaatliches Vorgehen gegen Deepfakes ist schwierig“ https://lnkd.in/e56gRhz2
@@ -1,29 +1,25 @@
---
title: "Kniepunkt #9"
title: '009: KI-Prophezeiung'
issue: 9
date: 2025-10-25
tags: [ki, ethics]
summary: ""
date: 2025-10-25T00:00:00.000Z
tags:
- ki
- ethics
summary: ''
visibility: primary
source: linkedin-post
linkedin_url: "https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7387926587158974464"
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7387926587158974464'
image: /images/kniepunkt/009-cover.webp
---
Kniepunkt 009: KI Prophezeiung"
"
"Am Anfang öffnete sich das Meer ... Pardon, der Browser. "
"OpenAI nennt ihn Atlas, doch er wirkt eher wie Moses Stab: Ein Klick genügt, und die Fluten des Internets teilen sich, sodass wir sicher hindurchscrollen können. Nur wartet am anderen Ufer kein gelobtes Land, sondern ein Ökosystem, in dem wir selbst die Opfergaben sind. Klick für Klick, Cookie für Cookie."
"
"Dann kam Sora, die falsche Prophetin des Bildes. Ihre Visionen sind schärfer, schöner und glaubhafter als die Wirklichkeit. Warum noch prüfen, ob ein Wunder echt ist, wenn es ohnehin besser aussieht als das Original? Wer braucht die Apokalypse, wenn der Algorithmus uns täglich eine neue in 4K mit Sounddesign liefert?"
"
"Und schließlich betritt Claude die Kanzel. Er verspricht, unsere Sünden zu verwalten: Er werde nichts vergessen, was wir ihm anvertrauen, aber auch nichts durcheinanderbringen. Ein digitaler Beichtstuhl, betrieben von einer Firma, die schon ganze Bibliotheken vernichtet hat. Aber immer steht die Ethik als Hauptverkaufsargument im Vordergrund."
"
"Vielleicht sollten wir den nächsten Login mit einem Kreuzzeichen beginnen. Denn die neue Religion des Wissens verlangt keine Glaubensbekenntnisse mehr, sondern nur noch AGBs... und eventuell eine Kreditkarte."
"
"-----"
"Themen diese Woche:"
"OpenAI Atlas Browser: https://lnkd.in/ej8bRzfR"
"
"NewsGuard zu Sora 2 Deepfakes: https://lnkd.in/e2VFJRAh"
"
"Anthropic Memory Update: https://lnkd.in/eUb6AbCT
Kniepunkt 009: KI Prophezeiung
Am Anfang öffnete sich das Meer ... Pardon, der Browser.
OpenAI nennt ihn Atlas, doch er wirkt eher wie Moses Stab: Ein Klick genügt, und die Fluten des Internets teilen sich, sodass wir sicher hindurchscrollen können. Nur wartet am anderen Ufer kein gelobtes Land, sondern ein Ökosystem, in dem wir selbst die Opfergaben sind. Klick für Klick, Cookie für Cookie.
Dann kam Sora, die falsche Prophetin des Bildes. Ihre Visionen sind schärfer, schöner und glaubhafter als die Wirklichkeit. Warum noch prüfen, ob ein Wunder echt ist, wenn es ohnehin besser aussieht als das Original? Wer braucht die Apokalypse, wenn der Algorithmus uns täglich eine neue in 4K mit Sounddesign liefert?
Und schließlich betritt Claude die Kanzel. Er verspricht, unsere Sünden zu verwalten: Er werde nichts vergessen, was wir ihm anvertrauen, aber auch nichts durcheinanderbringen. Ein digitaler Beichtstuhl, betrieben von einer Firma, die schon ganze Bibliotheken vernichtet hat. Aber immer steht die Ethik als Hauptverkaufsargument im Vordergrund.
Vielleicht sollten wir den nächsten Login mit einem Kreuzzeichen beginnen. Denn die neue Religion des Wissens verlangt keine Glaubensbekenntnisse mehr, sondern nur noch AGBs... und eventuell eine Kreditkarte.
-----
Themen diese Woche:
OpenAI Atlas Browser: https://lnkd.in/ej8bRzfR
NewsGuard zu Sora 2 Deepfakes: https://lnkd.in/e2VFJRAh
Anthropic Memory Update: https://lnkd.in/eUb6AbCT
@@ -1,39 +1,30 @@
---
title: "Kniepunkt #10"
title: '010: KI-Therapie'
issue: 10
date: 2025-11-01
tags: [ki]
summary: ""
date: 2025-11-01T00:00:00.000Z
tags:
- ki
summary: ''
visibility: primary
source: linkedin-post
linkedin_url: "https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7390492064695730176"
linkedin_url: 'https://www.linkedin.com/feed/update/urn%3Ali%3Ashare%3A7390492064695730176'
image: /images/kniepunkt/010-cover.webp
---
Kniepunkt 010: KI Therapie"
"
"Platon und Freud gehen in eine KI-Bar."
"Platon hebt das Glas und sagt: „Auf die Erkenntnis!“ "
"Freud korrigiert: „Auf die unterdrückten Emotionen.“ "
"Der Bar-KIper euphorisch: „Abo für Gruppentherapie verfügbar!“"
"
"Während Philosophen noch von Erkenntnis sprachen, haben wir die Couch digitalisiert. Millionen Menschen tippen ihre Sorgen in Chatfenster, die trösten, coachen und manchmal sogar warnen sollen. In den USA testen Kinder KI-Therapie-Apps, die statt zuzuhören Protokolle exportieren. „Kostenlos“ heißt hier, dass Du mit deiner Gesundheit zahlst."
"
"Wir könnten natürlich auch in mehr Psycholog:innen investieren. Das wäre jedoch teuer, unsexy und schwer skalierbar. Also hoffen wir, dass KI irgendwann echte Hilfe wird - reguliert, reflektiert und haftbar."
"
"Und tatsächlich: Forschende bei Anthropic haben Sprachmodellen jüngst so etwas wie Gedanken implantiert. In ihren neuronalen Schichten erkennen sie Muster, inklusive ihrer Komplexe. Das ist ein erster Schritt zur maschinellen Selbstreflexion und möglicherweise sogar zur digitalen Supervision?"
"
"Wenn wir der KI Depressionen beibringen, lernen wir möglicherweise, unsere eigenen besser zu behandeln. Denn wie schon Platon und Freud wussten, beginnt Heilung mit Erkenntnis ... auch wenn sie diesmal aus künstlichen Neuronen kommt."
"
"
"-------"
"Zum Vertiefen: "
"
"Anthropic Research Team (29.10.2025): „Introspective Language Models“. "Nachweis" interner Selbstwahrnehmung in Sprachmodellen. https://lnkd.in/e4MKmzRK"
"
"The Decoder (30.10.2025): „Sprachmodelle können laut Anthropic ihre eigenen internen Zustände wahrnehmen“. Zusammenfassung der Anthropic-Forschung. https://lnkd.in/e8SWvSg9"
"
"Stanford HAI (11.06.2025): „Exploring the dangers of AI in mental health care“. Risiken von KI-Therapie-Apps, besonders bei Kindern. https://lnkd.in/e2sdVTGP"
"
"BMJ (08.05.2025): „The risks and benefits of AI therapy tools“. Analyse von 20 000 Therapie-Apps ohne klinische Prüfung. https://lnkd.in/eeEaeE3J"
"
"MentalHealthCampaign.org (12.03.2025): „Psychologists Sound the Alarm on AI Chatbots for Mental Health“. Kritik an unkontrollierter Nutzung von KI-Therapiechatbots. https://lnkd.in/e896JPKJ
Kniepunkt 010: KI Therapie
Platon und Freud gehen in eine KI-Bar.
Platon hebt das Glas und sagt: „Auf die Erkenntnis!“
Freud korrigiert: „Auf die unterdrückten Emotionen.“
Der Bar-KIper euphorisch: „Abo für Gruppentherapie verfügbar!“
Während Philosophen noch von Erkenntnis sprachen, haben wir die Couch digitalisiert. Millionen Menschen tippen ihre Sorgen in Chatfenster, die trösten, coachen und manchmal sogar warnen sollen. In den USA testen Kinder KI-Therapie-Apps, die statt zuzuhören Protokolle exportieren. „Kostenlos“ heißt hier, dass Du mit deiner Gesundheit zahlst.
Wir könnten natürlich auch in mehr Psycholog:innen investieren. Das wäre jedoch teuer, unsexy und schwer skalierbar. Also hoffen wir, dass KI irgendwann echte Hilfe wird - reguliert, reflektiert und haftbar.
Und tatsächlich: Forschende bei Anthropic haben Sprachmodellen jüngst so etwas wie Gedanken implantiert. In ihren neuronalen Schichten erkennen sie Muster, inklusive ihrer Komplexe. Das ist ein erster Schritt zur maschinellen Selbstreflexion und möglicherweise sogar zur digitalen Supervision?
Wenn wir der KI Depressionen beibringen, lernen wir möglicherweise, unsere eigenen besser zu behandeln. Denn wie schon Platon und Freud wussten, beginnt Heilung mit Erkenntnis ... auch wenn sie diesmal aus künstlichen Neuronen kommt.
-------
Zum Vertiefen:
Anthropic Research Team (29.10.2025): „Introspective Language Models“. "Nachweis" interner Selbstwahrnehmung in Sprachmodellen. https://lnkd.in/e4MKmzRK
The Decoder (30.10.2025): „Sprachmodelle können laut Anthropic ihre eigenen internen Zustände wahrnehmen“. Zusammenfassung der Anthropic-Forschung. https://lnkd.in/e8SWvSg9
Stanford HAI (11.06.2025): „Exploring the dangers of AI in mental health care“. Risiken von KI-Therapie-Apps, besonders bei Kindern. https://lnkd.in/e2sdVTGP
BMJ (08.05.2025): „The risks and benefits of AI therapy tools“. Analyse von 20 000 Therapie-Apps ohne klinische Prüfung. https://lnkd.in/eeEaeE3J
MentalHealthCampaign.org (12.03.2025): „Psychologists Sound the Alarm on AI Chatbots for Mental Health“. Kritik an unkontrollierter Nutzung von KI-Therapiechatbots. https://lnkd.in/e896JPKJ
@@ -0,0 +1,31 @@
---
title: '011: Ethik weggeklickt?'
date: 2025-11-09T00:00:00.000Z
tags:
- ki
- ai-act
- ethics
- data
summary: ''
source: linkedin-article
visibility: primary
linkedin_url: 'https://www.linkedin.com/pulse/011-ethik-weggeklickt-andr%C3%A9-knie-j42ge'
image: /images/kniepunkt/011-cover.webp
---
Europa klickt wieder. Diesmal nicht auf einen göttlichen Stier, sondern auf „Ich stimme zu“. Diese Woche: München zieht in die Microsoft-Cloud, Brüssel denkt über eine Beschneidung des AI Act nach und Google und Apple bilden eine unheilige Allianz. Und wir? Wir reden über Ethik und drücken trotzdem genervt auf den Zustimmungsbutton, damit das Fenster endlich verschwindet.
Die neue europäische Tugend heißt Scheinethik. Wir diskutieren über Datenschutz, während wir auf „Weiter“ klicken. Nicht, weil wir überzeugt sind, sondern weil das Kästchen im Weg steht und die Zeit drängt. Wir müssen auf den KI-Stier aufspringen, bevor die Blase platzt. Immerhin hat Nvidia diese Woche hunderte Milliarden an der Börse verloren. Und irgendwo lacht ein Algorithmus, weil er weiß, dass Moral immer langsamer lädt als ein Cookie-Banner.
In der Mythologie ließ sich Europa schon einmal von einem Stier entführen. Damals war es hauptsächlich aus Neugier. Heute reitet sie wieder, diesmal digital.
Vielleicht ist das der eigentliche Fortschritt: Wir haben aus der Mythologie gelernt, wie man sich mit einem Klick freiwillig entführen lässt.
## Zum Weiternachdenken:
[https://www.heise.de/news/Vertrag-soll-bis-Jahresende-stehen-Bayern-will-in-die-Microsoft-Cloud-11066618.html](https://www.heise.de/news/Vertrag-soll-bis-Jahresende-stehen-Bayern-will-in-die-Microsoft-Cloud-11066618.html)
[https://www.theguardian.com/world/2025/nov/07/european-commission-ai-artificial-intelligence-act-trump-administration-tech-business](https://www.theguardian.com/world/2025/nov/07/european-commission-ai-artificial-intelligence-act-trump-administration-tech-business)
[https://www.br.de/nachrichten/netzwelt/milliardendeal-fuer-siri-apple-wird-jetzt-google-kunde,V1rSKkZ](https://www.br.de/nachrichten/netzwelt/milliardendeal-fuer-siri-apple-wird-jetzt-google-kunde,V1rSKkZ)
[https://www.finanztrends.de/news/nvidia-aktie-auf-verliererseite/](https://www.finanztrends.de/news/nvidia-aktie-auf-verliererseite/)
@@ -1,15 +0,0 @@
---
title: "Kniepunkt #11"
issue: 11
date: 2025-11-08
tags: [ki, ethics]
summary: ""
visibility: primary
source: linkedin-post
linkedin_url: "https://www.linkedin.com/feed/update/urn%3Ali%3AugcPost%3A7393043380290883585"
---
Kniepunkt 011: Ethik weggeklickt? "
"Die Zeit rennt, ethische Entscheidungen dauern zu lange, der consent Knopf ist soo verlockend. Lest meine Kolumne ab heute im Newsletter-Format. "
"
"Nach 10 Folgen glaube ich, dass es auch weitergehen wird, mit absurden widersprüchlichen Nachrichten rund um Digitalisierung, KI, Ethik und Verantwortung. Deshalb habe ich einen Newsletter aufgesetzt und werde ab jetzt weiterhin die Dinge aufschreiben, die mich verwundern, verstören oder einfach nur zum Lachen bringen. Gebt mir gerne Feedback, als DM oder in den Kommentaren und ab heute könnt Ihr auch abonnieren. Ich freue mich, wenn Euch meine Bilder (KI generierte Pixel- oder allegorischer Art) gefallen. Mir macht es jedenfalls Spaß es zu gestalten und zu schreiben und so versuche ich ab heute mit dem Newsletter etwas Neues.
@@ -1,12 +1,15 @@
---
title: "KNIEPUNKT 12: KI Soundtrack"
title: '012: KI-Soundtrack'
issue: 12
date: 2025-11-16
tags: [ki]
summary: ""
date: 2025-11-16T00:00:00.000Z
tags:
- ki
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-12-ki-soundtrack-andr%C3%A9-knie-n6aie"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-12-ki-soundtrack-andr%C3%A9-knie-n6aie
image: /images/kniepunkt/012-cover.webp
---
Unsere Gesellschaft sitzt im Aufnahmestudio und nimmt die „Symphonie der Mittelmäßigkeit” auf. In München dreht die GEMA am Regler des Urheberrechts, das Gericht bestätigt: OpenAI hat sich an Songtexten vergangen.
@@ -1,12 +1,15 @@
---
title: "KNIEPUNKT 013: KI Kundenerfahrung"
title: '013: KI-Kundenerfahrung'
issue: 13
date: 2025-11-23
tags: [ki]
summary: ""
date: 2025-11-23T00:00:00.000Z
tags:
- ki
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-013-ki-kundenerfahrung-andr%C3%A9-knie-e0ere"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-013-ki-kundenerfahrung-andr%C3%A9-knie-e0ere
image: /images/kniepunkt/013-cover.webp
---
Amazon wirft Perplexity vor, sein Einkaufsagent verschleiere Identität und Absicht. Das klingt nach Cybercrime, bedeutet in diesem Fall jedoch lediglich, dass eine KI Preise vergleicht, ohne zuzugeben, dass sie keine menschliche Person ist. Ausgerechnet der Konzern, der uns seit Jahren mit Empfehlungslogik zu „Kunden, die auch X kauften“ macht, stilisiert sich nun zum Hüter einer ehrlichen Customer Experience.
@@ -1,12 +1,16 @@
---
title: "KNIEPUNKT 014: KI-Entropie"
title: '014: KI-Entropie'
issue: 14
date: 2025-11-30
tags: [ki, change, energy]
summary: ""
date: 2025-11-30T00:00:00.000Z
tags:
- ki
- change
- energy
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-014-ki-entropie-andr%C3%A9-knie-8ieze"
linkedin_url: 'https://www.linkedin.com/pulse/kniepunkt-014-ki-entropie-andr%C3%A9-knie-8ieze'
image: /images/kniepunkt/014-cover.webp
---
Ist Googlen das neue Googeln?
@@ -1,12 +1,16 @@
---
title: "KNIEPUNKT 15: KI Beichtstuhl"
title: '015: KI-Beichtstuhl'
issue: 15
date: 2025-12-07
tags: [ki, data]
summary: ""
date: 2025-12-07T00:00:00.000Z
tags:
- ki
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-15-ki-beichtstuhl-andr%C3%A9-knie-nj2ie"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-15-ki-beichtstuhl-andr%C3%A9-knie-nj2ie
image: /images/kniepunkt/015-cover.webp
---
Am Freitag habe ich noch darüber geschrieben, wie Atlas und Comet uns das Denken abnehmen, wenn wir es zulassen. Formulare ausfüllen, Flüge buchen, Websites lesen, während wir gedanklich schon beim Feierabendbier sind. Jetzt bekommt dieser Komfort eine neue Dimension: Wir bringen den Modellen das Beichten bei.
@@ -1,12 +1,16 @@
---
title: "KNIEPUNKT 016: KI Wirtshaus"
title: '016: KI-Wirtshaus'
issue: 16
date: 2025-12-14
tags: [ki, ethics]
summary: ""
date: 2025-12-14T00:00:00.000Z
tags:
- ki
- ethics
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-016-ki-wirtshaus-andr%C3%A9-knie-zbfof"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-016-ki-wirtshaus-andr%C3%A9-knie-zbfof
image: /images/kniepunkt/016-cover.webp
---
Im KI-Wirtshaus fließt Information wie Bier: trüb, schaumig und in reichlicher Menge. Am Tresen steht ein KI-Politiker und zapft Wahlversprechen. Morgen wird alles besser, günstiger und einfacher sein. Er hat nur den Auftrag, zu überzeugen, nicht die Wahrheit zu sagen. Eine Studie hat gezeigt, dass Chatbots Menschen sehr erfolgreich von politischen Parteien überzeugen können. Allerdings erfinden sie dafür Fakten.
@@ -1,12 +1,16 @@
---
title: "KNIEPUNKT 017: KI Weihnachten"
title: '017: KI-Weihnachten'
issue: 17
date: 2025-12-21
tags: [ki, automation]
summary: ""
date: 2025-12-21T00:00:00.000Z
tags:
- ki
- automation
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-017-ki-weihnachten-andr%C3%A9-knie-3zeme"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-017-ki-weihnachten-andr%C3%A9-knie-3zeme
image: /images/kniepunkt/017-cover.webp
---
Pünktlich zum Fest der Besinnlichkeit wird mir diese Tage die Frage gestellt, ob ich die Künstliche Intelligenz eigentlich kritisch sehe. Zugegeben, meine „Kniepunkte” nähren sich vornehmlich von der täglichen Absurdität, die uns die Tech-Giganten als Fortschritt servieren. Doch lasst mich eines klarstellen: Wer das Groteske benennt, ist noch lange kein Misanthrop. Im Gegenteil. Für mich ist KI ein wunderbares Werkzeug mit gigantischem Potenzial, der Menschheit zu nützen wenn wir es richtig einsetzen.
@@ -1,12 +1,15 @@
---
title: "KNIEPUNKT 018: KI KIgAI"
title: '018: ()K)IKIgAI'
issue: 18
date: 2025-12-28
tags: [ki, energy]
summary: ""
date: 2025-12-28T00:00:00.000Z
tags:
- ki
- energy
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-018-ki-kigai-andr%C3%A9-knie-wdxzf"
linkedin_url: 'https://www.linkedin.com/pulse/kniepunkt-018-ki-kigai-andr%C3%A9-knie-wdxzf'
image: /images/kniepunkt/018-cover.webp
---
KI-KIgAI: Erleuchtung im Rechenzentrum
@@ -1,12 +1,19 @@
---
title: "KNIEPUNKT 019: KI Hürdenlauf"
title: '019: KI-Hürdenlauf'
issue: 19
date: 2026-01-04
tags: [ki, sovereignty, mittelstand, change, data]
summary: ""
date: 2026-01-04T00:00:00.000Z
tags:
- ki
- sovereignty
- mittelstand
- change
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-019-ki-h%C3%BCrdenlauf-andr%C3%A9-knie-c28uf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-019-ki-h%C3%BCrdenlauf-andr%C3%A9-knie-c28uf
image: /images/kniepunkt/019-cover.webp
---
Willkommen im Sportjahr 2026!
@@ -1,12 +1,18 @@
---
title: "KNIEPUNKT 020: KI Amtsstube"
title: '020: KI-Amtsstube'
issue: 20
date: 2026-01-11
tags: [ki, sovereignty, ai-act, education]
summary: ""
date: 2026-01-11T00:00:00.000Z
tags:
- ki
- sovereignty
- ai-act
- education
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-020-ki-amtsstube-andr%C3%A9-knie-8ynwf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-020-ki-amtsstube-andr%C3%A9-knie-8ynwf
image: /images/kniepunkt/020-cover.webp
---
Während in Europa noch darüber debattiert wird, ob die Digitalisierung der Verwaltung eher Mythos oder Drohung ist, bahnt sich im Stillen eine „unsichtbare Revolution“ durch die Flure der deutschen Bundesbehörden. Der Bund wird mit KI geradezu „geflutet“ allerdings auf die deutsche Art: mit einer Closed-Source-Eigenentwicklung auf Basis von Open-Source-Modellen. Die Hoffnung ist groß, dass dies ein digitaler Befreiungsschlag gegen den Amtsschimmel sein könnte, ein Versuch, den Staat durch technologische Souveränität endlich wieder manövrierfähig zu machen.
@@ -1,12 +1,17 @@
---
title: "KNIEPUNKT 021: KI Miete"
title: '021: KI-Miete'
issue: 21
date: 2026-01-18
tags: [ki, sovereignty, ethics, data]
summary: ""
date: 2026-01-18T00:00:00.000Z
tags:
- ki
- sovereignty
- ethics
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-021-ki-miete-andr%C3%A9-knie-tmojf"
linkedin_url: 'https://www.linkedin.com/pulse/kniepunkt-021-ki-miete-andr%C3%A9-knie-tmojf'
image: /images/kniepunkt/021-cover.webp
---
Hast Du Dir eigentlich schon einmal überlegt, ob man Unabhängigkeit mieten kann? Es ist die große Verheißung dieser Tage: Souveränität als Service-Modell. Während ich diesen Text schreibe, liegt mein neuer Laptop neben mir, und der Download des Cinnamon-Builds von Linux Mint läuft. Ich habe beschlossen, meinen Sonntag zu investieren, um aus der schicken, aber fremdbestimmten Cloud-Wohnung auszuziehen. Ich baue mir mein eigenes digitales Haus.
@@ -1,12 +1,15 @@
---
title: "Kniepunkt 22: KI Ballsaal"
title: '022: KI-Ballsaal'
issue: 22
date: 2026-01-25
tags: [ki, data]
summary: ""
date: 2026-01-25T00:00:00.000Z
tags:
- ki
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-22-ki-ballsaal-andr%C3%A9-knie-bwyhf"
linkedin_url: 'https://www.linkedin.com/pulse/kniepunkt-22-ki-ballsaal-andr%C3%A9-knie-bwyhf'
image: /images/kniepunkt/022-cover.webp
---
Hast Du Dir schon mal gewünscht, Du könntest Dich klonen, um die ganze Arbeit zu erledigen? Die Firma Cursor hat das jetzt quasi durchgespielt mit KI. Sie sperrten hunderte KI-Agenten virtuell in einen Raum und gaben ihnen den Auftrag: „Baut uns einen Webbrowser. Von Null. In einer Woche.“
@@ -1,12 +1,16 @@
---
title: "Kniepunkt 023: tropischer Wind"
title: '023: tropischer Wind'
issue: 23
date: 2026-02-01
tags: [ki, data]
summary: ""
date: 2026-02-01T00:00:00.000Z
tags:
- ki
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-023-tropischer-wind-andr%C3%A9-knie-zjydf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-023-tropischer-wind-andr%C3%A9-knie-zjydf
image: /images/kniepunkt/023-cover.webp
---
Es gibt Wochen, in denen sich die Nachrichtenlage wie ein missglückter Software-Release anfühlt: Buggy, unübersichtlich und man möchte am liebsten den Stecker ziehen. Doch diese Woche weht ein anderer Wind durch das digitale Gebälk, ein fast schon tropischer. Er weht aus Anguilla, einem winzigen Koralleneiland in der Karibik, das bisher eher für Hummer und weißen Sand bekannt war. Heute ist die Insel das Silicon Valley der Staatsfinanzen. Warum? Weil die Geschichte der Technologie manchmal einen Humor hat, den kein Algorithmus simulieren kann. Anguilla besitzt die Top-Level-Domain „.ai“. Was für uns ein Kürzel für „Artificial Intelligence“ ist, ist für die 16.000 Inselbewohner die Lizenz zum Gelddrucken. Mit einer Wachstumsrate von einem Prozent pro Woche! spülen die Registrierungsgebühren Millionen in die Staatskasse. Das Beste daran ist, dass davon kein gläserner Büroturm gebaut, sondern eine kostenlose Krankenversicherung für Kinder und ein Zukunftsfonds finanziert werden.
@@ -1,12 +1,18 @@
---
title: "Kniepunkt 024: KI Arbeitswelt"
title: '024: KI-Arbeitswelt'
issue: 24
date: 2026-02-08
tags: [ki, sovereignty, leadership, education]
summary: ""
date: 2026-02-08T00:00:00.000Z
tags:
- ki
- sovereignty
- leadership
- education
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-024-ki-arbeitswelt-andr%C3%A9-knie-oyqge"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-024-ki-arbeitswelt-andr%C3%A9-knie-oyqge
image: /images/kniepunkt/024-cover.webp
---
Sogar in den Hauptnachrichten waren diese Woche die deutschen Synchronsprecher. Sie streiken, weil Netflix sie durch viel billigere und nie ermüdende KI ersetzen möchte. Die Schreiber und Schauspieler in Amerika waren einigermaßen erfolgreich und haben sich schon vor geraumer Zeit durch Streiks bereits durchgesetzt. Wahrscheinlich wäre heutzutage die Nationalgarde aufmarschiert…
@@ -1,12 +1,16 @@
---
title: "KNIEPUNKT 025: KI Dystopien"
title: '025: KI-Dystopien'
issue: 25
date: 2026-02-15
tags: [ki, sovereignty]
summary: ""
date: 2026-02-15T00:00:00.000Z
tags:
- ki
- sovereignty
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-025-ki-dystopien-andr%C3%A9-knie-d19cf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-025-ki-dystopien-andr%C3%A9-knie-d19cf
image: /images/kniepunkt/025-cover.webp
---
### Die Idylle an der Haustür
@@ -1,12 +1,19 @@
---
title: "KNIEPUNKT 026: Apokalyptische Akquise oder der Guru, die Puppenspieler und die mediale Fata Morgana"
title: '026: Apokalyptische Akquise'
issue: 26
date: 2026-02-22
tags: [ki, ai-act, mittelstand, education, automation]
summary: ""
date: 2026-02-22T00:00:00.000Z
tags:
- ki
- ai-act
- mittelstand
- education
- automation
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-026-apokalyptische-akquise-oder-der-guru-die-andr%C3%A9-knie-dorlf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-026-apokalyptische-akquise-oder-der-guru-die-andr%C3%A9-knie-dorlf
image: /images/kniepunkt/026-cover.webp
---
Wir befinden uns im Zeitalter der „apokalyptischen Akquise“. Sam Altman tourt nicht mehr als Visionär, sondern als klassischer Weltuntergangsguru durch die Welt. Die Botschaft ist so alt wie die Menschheit: Das Ende ist nah (in Form der Superintelligenz), und nur wer jetzt in die richtigen „Glaubensanteile“ investiert, wird gerettet. Es ist Sales im Sekten-Stil: Erst wird die existenzielle Angst geschürt, um dann die passende Regulierung natürlich maßgeschneidert für das eigene Monopol als Heilsbringer zu verkaufen. Während die seriöse Wissenschaft nüchtern feststellt, dass es sich um hochgezüchtete Statistik, aber sicher nicht um Bewusstsein handelt, rufen „Wissenschaftler“, die praktischerweise direkt die passende KI-Beratung im Portfolio haben, lautstark „AGI!“. Der Börsengang wird so nicht mit Fakten, sondern mit religiösem Eifer vergoldet.
@@ -1,12 +1,16 @@
---
title: "KNIEPUNKT 027: KI Glücksspiel"
title: '027: KI-Glücksspiel'
issue: 27
date: 2026-03-01
tags: [ki, sovereignty]
summary: ""
date: 2026-03-01T00:00:00.000Z
tags:
- ki
- sovereignty
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-027-ki-gl%C3%BCcksspiel-andr%C3%A9-knie-lajdf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-027-ki-gl%C3%BCcksspiel-andr%C3%A9-knie-lajdf
image: /images/kniepunkt/027-cover.webp
---
Hast Du schon einmal im digitalen Las Vegas übernachtet? Ich rede nicht von Poker-Bots, sondern vom neuesten Glücksspiel: **Clawdbot-Roulette**. Man setzt sich abends hin, füttert den Agenten mit einer vagen Idee und schaut berauscht zu, wie die Code-Zeilen über den Bildschirm tanzen. Es ist wie „Vibecoding“ auf Steroiden. Aber Vorsicht: Wer **Clawdbot** oder **Moltbook** ohne Limit und ohne doppeltes Netz nutzt, erlebt das, was ich den „agentischen Kater“ nenne. Du guckst morgens um fünf auf die Uhr, die Augen brennen, und in deinem Postfach wartet eine Rechnung der API-Provider, für die du dir auch einen gebrauchten Kleinwagen hättest kaufen können. Für viele ist das aktuell ein großartiges, aber verdammt teures Glücksspiel. Setzt Euch deshalb ein Limit, sonst wird das neue Projekt zum finanziellen oder zeitlichen Offenbarungseid.
@@ -1,12 +1,17 @@
---
title: "KNIEPUNKT 028: KI Turbulenzen"
title: '028: KI-Turbulenzen'
issue: 28
date: 2026-03-08
tags: [ki, leadership, data]
summary: ""
date: 2026-03-08T00:00:00.000Z
tags:
- ki
- leadership
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-028-ki-turbulenzen-andr%C3%A9-knie-edcuf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-028-ki-turbulenzen-andr%C3%A9-knie-edcuf
image: /images/kniepunkt/028-cover.webp
---
Es war einmal eine Firma, die hieß OpenAI. Das „Open“ stand für Transparenz, das „AI“ für die Rettung der Menschheit. Heute klingt das wie eine Sage aus dem letzten Jahrzehnt. In dieser Woche hat sich Sam Altman endgültig vom Kapuzenpulli des Weltretters verabschiedet und die Uniform des Rüstungspartners übergestreift. Ein Deal mit dem Pentagon (pardon, dem „Department of War“), um GPT in klassifizierten Netzwerken werkeln zu lassen. Die Reaktion der Community folgte prompt: Unter dem Hashtag #QuitGPT ziehen die Nutzer aus, als wäre OpenAI nicht mehr das gemütliche Wohnzimmer der Zukunft, sondern ein digitales Marsfeld. Es ist die alte Geschichte: Nichts korrumpiert so zuverlässig wie die Aussicht auf ein unendliches Budget. Wer braucht schon die Liebe der Nerds, wenn er die Schlüssel zum Arsenal der Demokratie hat?
@@ -1,13 +1,22 @@
---
title: "Kniepunkt 029: KI Nudelsuppe"
title: '029: KI-Nudelsuppe'
issue: 29
date: 2026-03-15
tags: [ki, change, ethics]
summary: ""
date: 2026-03-15T00:00:00.000Z
tags:
- ki
- change
- ethics
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-029-ki-nudelsuppe-andr%C3%A9-knie-el7mf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-029-ki-nudelsuppe-andr%C3%A9-knie-el7mf
image: /images/kniepunkt/029-cover.webp
---
> Der neue Kniepunkt ist da.Heute geht es um die Frage was Instant Nudeln mit Mauszeigern zu tun haben. Und warum Oracle 30.000 Menschen entlassen muss, um KI Hardware zu kaufen, obwohl Alibaba zeigt, dass die vergleichbare Performance auch auf einem Smartphone abrufbar wäre. Und natürlich gibt es wieder ein schönes Beispiel dafür, dass KI Governance viel langsamer ist, als die Entwicklung der KI. Fazit: Spannende Woche...Ich freue mich, über Eure Kommentare und Nachrichten! Gelesen wird alles, und auch noch auf fast alles geantwortet. 😉
---
Hattet ihr diese Woche auch das Gefühl, dass die KI-Entwicklung mittlerweile in der „Instant-Nudel-Phase“ angekommen ist? Kaum hat man das eine Modell verdaut, serviert OpenAI schon das nächste: GPT-5.4, gerade einmal 48 Stunden nach seinem Vorgänger. Vermutlich, um von dem gerade abgeschlossenen ethisch fragwürdigen Pentagon-Deal abzulenken. Das Neue an GPT 5.4 ist die native agentische Fähigkeit. Während wir noch darüber philosophieren, ob die KI ein Bewusstsein hat, klickt sie sich bereits durch unsere Excel-Tabellen und füllt Formulare aus. Mit einer Erfolgsquote von über 75 % bei der nativen Computersteuerung schlägt es im Benchmark erstmals die menschliche Basislinie. Es ist die technologische Realisierung der „Agentic AI“: ein digitaler Diener, der nicht nur antwortet, sondern auch handelt Halluzinationen inklusive.
@@ -1,12 +1,16 @@
---
title: "KNIEPUNKT 030: Heiße KI-Luft"
title: '030: Heiße KI-Luft'
issue: 30
date: 2026-03-22
tags: [ki, change]
summary: ""
date: 2026-03-22T00:00:00.000Z
tags:
- ki
- change
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-030-hei%C3%9Fe-ki-luft-andr%C3%A9-knie-ma2wf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-030-hei%C3%9Fe-ki-luft-andr%C3%A9-knie-ma2wf
image: /images/kniepunkt/030-cover.webp
---
Im Silicon Valley wird derzeit so viel heiße Luft produziert, dass man damit problemlos einen Heißluftballon bis zum Mars schicken könnte * ja, ich akzeptiere die physikalische Unkorrektheit, weil ich das Bild so schön finde.* Nehmen wir das hochgelobte Start-up Cursor: Mit geschmeidigen 29 Milliarden Dollar bewertet, feierte man sich gerade erst für eine geniale KI-Eigenentwicklung. Dumm nur, dass findige Entwickler innerhalb von 24 Stunden herausfanden, dass unter der Haube heimlich, still und leise das chinesische Modell Kimi K2.5 schnurrt. Ein Etikettenschwindel der feinsten Sorte. Und während man im Westen noch über astronomische Unternehmensbewertungen und Token-Preise halluziniert, bauen die Chinesen mit Modellen wie MiniMax M2.7 längst KIs, die sich munter selbst optimieren und weiterentwickeln.
@@ -1,12 +1,19 @@
---
title: "KNIEPUNKT 031: KI-Verkäufer statt KI-Spielberg"
title: '031: KI-Verkäufer statt KI-Spielberg'
issue: 31
date: 2026-03-29
tags: [ki, ai-act, mittelstand, change, data]
summary: ""
date: 2026-03-29T00:00:00.000Z
tags:
- ki
- ai-act
- mittelstand
- change
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-031-ki-verk%C3%A4ufer-statt-ki-spielberg-andr%C3%A9-knie-jishf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-031-ki-verk%C3%A4ufer-statt-ki-spielberg-andr%C3%A9-knie-jishf
image: /images/kniepunkt/031-cover.webp
---
### Vom Regiestuhl an die Supermarktkasse
@@ -1,12 +1,19 @@
---
title: "KNIEPUNKT 032: KI-Ostereier"
title: '032: KI-Ostereier'
issue: 32
date: 2026-04-05
tags: [ki, sovereignty, mittelstand, leadership, data]
summary: ""
date: 2026-04-05T00:00:00.000Z
tags:
- ki
- sovereignty
- mittelstand
- leadership
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-032-ki-ostereier-andr%C3%A9-knie-sxpmf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-032-ki-ostereier-andr%C3%A9-knie-sxpmf
image: /images/kniepunkt/032-cover.webp
---
### Von künstlichen Gefühlen und echter Souveränität
@@ -1,12 +1,20 @@
---
title: "KNIEPUNKT 033: KI-Verschwendung"
title: '033: KI-Verschwendung'
issue: 33
date: 2026-04-12
tags: [ki, sovereignty, change, ethics, education, data]
summary: ""
date: 2026-04-12T00:00:00.000Z
tags:
- ki
- sovereignty
- change
- ethics
- education
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-033-ki-verschwendung-andr%C3%A9-knie-t0zzf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-033-ki-verschwendung-andr%C3%A9-knie-t0zzf
image: /images/kniepunkt/033-cover.webp
---
### Vom Token-Wahn zur moralischen Bedeutungslosigkeit
@@ -1,12 +1,18 @@
---
title: "KNIEPUNKT 034: ungeprüfte KI-Gewissheit"
title: '034: ungeprüfte KI-Gewissheit'
issue: 34
date: 2026-04-19
tags: [ki, leadership, ethics, data]
summary: ""
date: 2026-04-19T00:00:00.000Z
tags:
- ki
- leadership
- ethics
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-034-ungepr%C3%BCfte-ki-gewissheit-andr%C3%A9-knie-w39cf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-034-ungepr%C3%BCfte-ki-gewissheit-andr%C3%A9-knie-w39cf
image: /images/kniepunkt/034-cover.webp
---
Fast die Hälfte der Menschen in Deutschland glaubt inzwischen, KI-generierte Inhalte erkennen zu können. Nur 28 Prozent suchen aber nach Unstimmigkeiten im Bild, und nur 19 Prozent prüfen aktiv die Quelle. Das Vertrauen in die eigene Urteilskraft wächst also schneller als die Bereitschaft zur Überprüfung. Wir schauen auf ein Bild, lesen einen Absatz, nicken kurz und halten uns schon für aufgeklärt. Wird Medienkompetenz zum Gefühl?
@@ -1,12 +1,16 @@
---
title: "KNIEPUNKT 035: KI-Medizin"
title: '035: KI-Medizin'
issue: 35
date: 2026-04-26
tags: [ki, change, data]
summary: ""
date: 2026-04-26T00:00:00.000Z
tags:
- ki
- change
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-035-ki-medizin-andr%C3%A9-knie-fqkxf"
linkedin_url: 'https://www.linkedin.com/pulse/kniepunkt-035-ki-medizin-andr%C3%A9-knie-fqkxf'
image: /images/kniepunkt/035-cover.webp
---
Es sind Nachrichtenwochen wie diese, in denen ich mich frage, ob das Silicon Valley und die Weltpolitik heimlich von einer Horde satirischer Drehbuchautoren übernommen wurden. Auf der einen Seite erleben wir den absoluten Triumph des menschlichen Erfindergeistes. KI-Modelle wie Rosalind beschleunigen die Medikamentenentwicklung derart dramatisch, dass Krankheiten bald schneller entschlüsselt werden, als wir „Gesundheit“ sagen können. Es ist der Beweis, dass Künstliche Intelligenz uns unendlich bereichern kann, wenn wir sie für die großen, sinnvollen Fragen der Menschheit einsetzen.
@@ -1,12 +1,19 @@
---
title: "Kniepunkt 036: KI-Roboter(hype)"
title: '036: KI-Roboter(hype)'
issue: 36
date: 2026-05-03
tags: [ki, ai-act, leadership, automation, data]
summary: ""
date: 2026-05-03T00:00:00.000Z
tags:
- ki
- ai-act
- leadership
- automation
- data
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-036-ki-roboterhype-andr%C3%A9-knie-a65xf"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-036-ki-roboterhype-andr%C3%A9-knie-a65xf
image: /images/kniepunkt/036-cover.webp
---
Diese Woche kam mir das Thema Roboter allgegenwärtig vor. Unser Kanzler aus dem Sauerland lässt sich von "tanzenden" Robotern beeindrucken. Ein Roboter hat einen Halbmarathon in 50 Minuten gewonnen und ein anderer hat Tischtennisprofis besiegt. Irgendwie beeindruckt mich das wenig. Natürlich können solche hochgezüchteten Zirkuspferd-Roboter gewisse Dinge besser als Menschen. Warum sonst setzen wir sie seit Jahrzehnten in der Produktion ein. Damit Elon Musks Vision "es wird in 2040 mehr Roboter als Menschen auf der Erde geben" Wirklichkeit werden kann, müssten sie allerdings mehr als nur eine Disziplin beherrschen. Die Mehrheit der Menschen wünscht sich einen Roboter, der die Spülmaschine einräumt, einkauft und die Toilette sauber macht. Idealerweise kann er auch noch unseren Hintern abwischen, falls nötig. Ein solcher Roboter ist aber noch einige Jahre weg und da hilft auch die Entwicklungsgeschwindigkeit der KI nicht. Roboter werden immer günstiger und dank KI auch immer mehr Routineaufgaben in der Produktion übernehmen können, aber der Prozess läuft schon seit Jahrzehnten und der aktuelle Medienrummel ist reiner Hype und Werbung.
@@ -1,12 +1,19 @@
---
title: "KNIEPUNKT 037: KI-Autopilot mit Tagträumen"
title: '037: KI-Autopilot mit Tagträumen'
issue: 37
date: 2026-05-10
tags: [ki, sovereignty, ai-act, change, automation]
summary: ""
date: 2026-05-10T00:00:00.000Z
tags:
- ki
- sovereignty
- ai-act
- change
- automation
summary: ''
visibility: primary
source: linkedin-article
linkedin_url: "https://www.linkedin.com/pulse/kniepunkt-037-ki-autopilot-mit-tagtr%C3%A4umen-andr%C3%A9-knie-jjo3e"
linkedin_url: >-
https://www.linkedin.com/pulse/kniepunkt-037-ki-autopilot-mit-tagtr%C3%A4umen-andr%C3%A9-knie-jjo3e
image: /images/kniepunkt/037-cover.webp
---
Diese Woche gab es wieder neue Milliarden, neue Tools und neue Entlassungen wegen KI. Das kommt gefühlt aktuell aber in jeder neuen Woche vor. Deshalb kümmere ich mich heute um die Frage, wer hier eigentlich noch am Steuer sitzt. Sowohl vor Gericht als auch im Recruiting herrscht mittlerweile dichter Nebel. Da KI-generierte Schriftsätze und Lebensläufe die Systeme verstopfen, wird nach dem Radar gerufen, welches natürlich wieder von einer KI betrieben wird. Wir haben das Fahren outgesourct und delegieren nun konsequenterweise auch das Aus-dem-Fenster-schauen, das Tagträumen, an die Maschine.

Some files were not shown because too many files have changed in this diff Show More