Files
werkator/docs/werkator.werkbaum
claude-code 9e6dff6bbc
werkator build succeeded after 02:48
werkator/deploy build succeeded after 00:12
werkator/mutation build succeeded after 27:54
The values of a build's variables no longer stand on the command line of werkdock and docker (v1.43.6) (#166)
Co-authored-by: claude-code <claude-code@javagil.de>
2026-10-21 21:26:20 +02:00

491 lines
21 KiB
Plaintext

%% Werkator, planned with Werkbaum (https://werkbaum.javagil.de): what exists, what was dropped, what comes next.
%% Status: [^] live on mih09 or in use, [x] merged but not in use, [~] in work, [ ] planned, [?] idea, [-] dropped.
%% Each PR updates this file; see docs/agentic-workflow.md. The block behind --- explains the nodes with an id.
%% mih09 deploys every merge to main itself, so a merged node is [^].
[~] #wk: Werkator https://git.javagil.de/mi/werkator
- [~] #exec: Build execution and executor
- [^] Async executor, worktrees, logs, cancel (L)
" Plan steps 01 and 04, v0.9.0.
" Builds run in .git/werkator/worktrees per branch.
- [^] Shutdown marks builds INTERRUPTED, recovery re-runs them (S)
" v0.9.5
- [^] "Build current head" on the Branches view (S)
" PR#3, v1.0.1
- [^] Configurable executor.buildTimeout (S)
" PR#48; default 30 minutes.
- [^] A push during a running build is not lost (S)
" PR#57
- [^] Processor time per build (M)
" PR#67, PR#68, PR#71, PR#73
" Docker builds record none: the work runs under the daemon.
- [^] Phase timing and executor.overheadBudget (M)
" PR#70, plan step 14
- [^] Cancel replaces delete for active builds (S)
" PR#95, PR#98; a cancelled queued build is recorded at once.
- [^] executor.maxConcurrentPerRepository (S)
" PR#103
- [^] Executor decisions split into classes (M)
" PR#99, PR#106, PR#108, PR#109: BuildSlots, ActiveBuilds, CommandProcess, BuildLogs.
- [^] One werkdock import per image (S)
" PR#121; new status "build environment failed".
- [^] CI=true in every build (XS)
" PR#132; part of RFC 0006 step 2.
- [ ] Ownership repair after Docker builds (S)
" Plan step 14 item 3; Docker only (vm4006).
" Needs a container test.
- [?] Cancel on a new commit instead of queue-behind (S)
" Deferred in plan step 06.
- [?] Warning when a build nears its timeout (XS)
" PR#48
- [~] #sandbox: Sandboxes: Docker, bwrap and werkdock
- [^] Docker build runtime (M)
" Plan step 11
- [^] Read-only git metadata in Docker builds (S)
" Plan step 16
- [^] Nightly Docker prune timer (S)
" PR#80 removes anonymous volumes; PR#83 keeps the build images.
- [^] bwrap user-namespace runtime for Managed Webspaces (L)
" PR#4, ADR 0008, plan step 17
- [^] Werkdock in its own repository; Werkator uses its CLI (L)
" PR#6, PR#7, PR#15, plan step 21
- [^] Config section bwrap renamed werkdock (S)
" PR#19, PR#131; the old name is read with a warning.
- [^] werkdock import verb and stale-binary rebuild (M)
" PR#50
- [^] Testcontainers over the werkdock API socket on the webspace (S)
" PR#53
- [^] One shared Gradle home: werkdock.gradleHome (S)
" PR#76
- [^] Build environments that no configuration names are removed (S)
" PR#77
- [^] docker.socket opt-in and pinned (S)
" PR#55; PR#72 made it settable per build.
- [^] docker.env host override wins; rootlesskit host override (S)
" PR#85, PR#86
- [ ] Drop the "load -i --name" fallback (XS)
" PR#50; when every werkdock has import.
- [ ] #sandbox.alias: Drop the bwrap alias (XS) :#config.step18
" PR#19; together with plan step 18.
- [?] Disposable Docker daemon per build (M)
" PR#55; audit finding 3 is half fixed.
" DinD needs a rootful host daemon.
- [?] Bind mount for credential files in Docker follow-ups (S)
" PR#23
- [?] Shared .konan directory like gradleHome (XS)
" PR#76, PR#77
- [?] MemoryMax and TasksMax on the webspace unit (XS)
" PR#4
- [?] werkdock library mode: rootfs building blocks on the HDD (L)
- [-] #sandbox.proot: proot and fakechroot
- [-] #sandbox.native: Plain native builds with hand-installed toolchains
- [-] #sandbox.levels: Werkdock RFC 0002 levels 2 and 3
- [~] #config: Configuration, build definitions and pinning
- [^] Layered YAML config: machine, project, branch (M)
" v0.9.0
- [^] Build definitions: builds, trigger, ! excludes, statusContext (L)
" ADR 0007, v0.9.14 to v0.9.20
- [^] werkator.version since and below in config files (S)
" v0.9.18
- [^] init --apply fragment layer and control-token command (M)
" PR#8, PR#9, plan step 23
- [^] init reads its config from the repository root (XS)
" PR#22
- [^] A blank credential does not shadow an inherited one (S)
" PR#51
- [^] Shape check and pinned values written back after merge (S)
" PR#55
- [^] Config checks split for Mutation-CRAP (S)
" PR#112, PR#120, PR#131
- [ ] #config.step18: Remove the legacy branches section, set FORMAT_BROKE_IN (M)
" Plan step 18, the last open plan step.
" Needs every hs.hsadmin.ng branch config free of a top-level branches key.
- [ ] #config.gittally: Remove the .gittally.yml name fallback (S) :#config.step18
" PR#1; the old name is then rejected.
- [?] Should a branch be able to remove a build definition? (S)
" PR#15
- [?] Pin docker.env too (XS)
" Security audit TODO 6.
- [?] Gradle 9 upgrade (S)
" ADR 0002; waits for openapi-generator and ktlint support.
- [-] #config.autobuild: Keep extending autoBuild
- [-] #config.parallel: autoBuild and builds in parallel forever
- [-] #config.pinbuilds: Pin the whole builds section against the branch layer
- [-] #config.maxconc: builds.maxConcurrent
- [-] #config.secrets: Mark secrets in the WerkatorConfig schema
- [~] #watch: Watcher, triggers and follow-up builds
- [^] Branch polling, atTimes schedules, startup recovery (M)
" Plan step 06
- [^] Hourly ??:MM slots; local refs fast-forwarded (S)
" v0.9.11, v0.9.16
- [^] Watcher health banner for an unreachable origin (S)
" Plan step 19
- [^] Follow-up builds: trigger.afterSuccessOf (L)
" PR#23; a deployment is a build that follows a green build.
- [^] Branch-owned sandboxed follow-ups (S)
" PR#74
- [ ] #watch.list: afterSuccessOf as a list, like needs (S)
" PR#23; the same work as part of RFC 0006 step 3.
- [~] #multi: Multi-repository instance
- [^] ADR 0009, RepoContext, registry in ~/.werkator.yml, --repo (XL)
" PR#10, PR#11, PR#12, plan step 22 A to C
- [^] Repository-scoped routes /repos/<name> and /api/repos/<name> (M)
" PR#13, plan step 22 D
- [^] Rollout on mih09 (S)
" Plan step 22 E
- [?] Round-robin fairness across repositories (S)
" FIFO was decided on 2026-09-02.
- [?] Share buildenv rootfs trees across repositories (M)
" Waits for the Werkdock image store.
- [-] #multi.federation: Federation dashboard over single-repository instances
- [-] #multi.prefix: Repository prefix on artifactKey
- [~] #pr: Pull-request builds
- [^] requirePullRequest gate: build only branches with a PR (S)
- [^] Open PR shown as PR#n, then in its own column (S)
" PR#81, PR#82
- [^] Pull-request target builds: onPullRequestTarget, fresh home, own pool (L)
" PR#117, PR#118, PR#119, PR#120, PR#122
- [^] A commit status lost on a dead connection is sent once more (XS)
" PR#155; werkcrappit PR#68 stayed pending: ai-review/gate never got its success.
- [ ] Show the pull request target in the UI and the API DTOs (S)
" PR#117
- [?] Rebuild a reopened PR with an unchanged head (XS)
" PR#117
- [?] PR targets tile only where a target definition exists (XS)
" PR#119
- [~] #ui: Web UI
- [^] Thymeleaf pages and werkator.js polling; release-notes page (M)
" Plan step 08
- [^] Kin design: IBM Plex, logo, header, imprint and privacy links (L)
" RFC 0001; PR#34, PR#35, PR#38, PR#39
- [^] Repositories page /repos, GET /api/repos, repository line (M)
" PR#37
- [^] Instance home page and switchable dark mode (L)
" PR#54, RFC 0003
- [^] Mobile nav icons; control-token feedback (S)
" PR#56, PR#47
- [^] Build-duration trend per definition (M)
" PR#49, plan step 20
- [^] "Restarting" indicator during self-deployment (XS)
" PR#75
- [^] #restart2: Two restarts per row: same commit, newest commit (M)
" PR#150; follow-ups, also those a branch defines, and pull-request targets refuse the newest commit.
" PR#151 split BuildsApiController.restart again: the nightly gate measured 15.64.
- [^] A failure overtaken by a newer run or a deleted branch is shown as outdated (S)
" PR#156; grey in the History and the home strip, the reason in the tag's title.
- [^] Builds panel on the home page: running, queued, failed; five tiles per row (S)
" PR#160; pages 1440 px wide, failures of the last week that no build of the same name answers or runs again.
- [?] Three-state theme switch: light, dark, follow browser (XS)
" PR#54
- [?] Relative timestamps on cards (S)
" PR#54
- [?] History paging or range selector (S)
" PR#59
- [?] Duration trend shows CPU time; slow-drift detection (S)
" PR#67, PR#49
- [-] #ui.rfc0001: RFC 0001 options A to F
- [-] #ui.trendbranch: Duration trend per branch
- [^] #artifacts: Artifacts and history retention
- [^] File artifact store, retentionPerBranch (M)
" Plan step 05
- [^] Age-based retentionMaxAge (S)
- [^] Permanent latest-green links (S)
- [^] History survives its branch: branchGoneAt (M)
" PR#59
- [^] Run history outlives artifacts: artifactsPrunedAt (S)
" PR#84
- [^] Markdown reports in the artifact index (S)
" PR#88, PR#90
- [^] Artifact CORS; private artifacts, builds.<name>.publicArtifacts (L)
" PR#96, PR#114
- [-] #artifacts.sqlite: SQLite instead of JSON files
- [~] #metrics: System page and metrics
- [^] Metrics page; critical utilization highlighted (M)
" Plan step 09
- [^] Quota-aware disk metrics (M)
" PR#16; PR#63: an unreadable quota is not the volume.
- [^] Health page: PSI, load, swap, three-tier history (L)
" PR#27, merged as PR#29
- [^] Multiple disks: metrics.disks (M)
" PR#33
- [^] Charts, disk breakdown dialog, physical-headroom marker (L)
" PR#40, PR#41, RFC 0002
- [^] Storage pressure sampled from /proc/pressure/io (S)
" PR#69
- [^] Swap thresholds and verdict colours (S)
" PR#100, PR#101, PR#102
- [^] Sampling and view split into steps; disk verdict judges budget and volume (M)
" PR#111, PR#116
- [^] Swap-out card with history; cards in one row (M)
" PR#146
- [^] OOM kills tile; tiles in two rows of four (S)
" PR#147
- [?] Charts for load and pressure on /system (S)
" PR#54
- [?] Fill the CPU value from history right after a restart (XS)
- [?] Feed the pressure figures into the verdict or the sizing (S)
" PR#69; needs about a month of pressure history.
- [?] Per-repository disk breakdown (S)
" RFC 0002 decision 4
- [?] Slice palette: buildenv and other differ (XS)
- [-] #metrics.a2: RFC 0002 A2: stacked bar in the disk card
- [-] #metrics.b2: RFC 0002 B2: second card
- [-] #metrics.switch: metrics.disk quota or filestore switch
- [~] #sizing: Capacity sizing
- [^] Capacity advice (M)
" PR#30, merged as PR#32
- [^] Sizing corrections and Hostsharing order mail (M)
" PR#42, PR#44
- [^] Sizing by waiting, in bookable steps (L)
" PR#58, RFC 0004
- [^] Disk sized by the level it holds; RAM downsize without the 40 % gate (S)
" PR#78, PR#79
- [^] CPU, RAM and disk advice split into steps (S)
" PR#113, PR#123
- [ ] Read oom_kill into the RAM verdict (S)
" RFC 0004, PR#58; waits for data, not for a node.
" Needs experience with the machine-wide counter.
- [ ] RAM sizing rule on swap-out (S)
" PR#102, PR#146; waits for data, not for a node.
" Needs weeks of the swapOut series, recorded since 2026-10-10.
- [?] Bookable steps from a Hostsharing API (M)
" RFC 0004 B1
- [~] #selfdeploy: Self-deployment
- [^] Static maintenance page during restarts (S)
" PR#17
- [^] RFC 0005 step 1: tools/self-deploy, staged swap, watchdog (M)
" PR#61
- [^] Adoptium toolchain: the runtime starts on the glibc of Debian 12 (S)
" PR#62
- [^] Temurin 25 in the toolchain and in the runtime bundle (S)
" PR#152, werkregie ADR 0001; Kotlin 2.4.21, Gradle stays 8.14.5.
- [^] Runtime swapped only while the service is down (S)
" PR#64
- [^] restartsInstance: the instance drains and ends itself (M)
" PR#65, PR#66, RFC 0005 step 2
- [^] Restart only from a repository with selfDeploys: true (S)
" PR#87
- [?] Self-deployment on a Docker host with a system unit (M)
" Needs a new RFC.
- [-] #selfdeploy.pathunit: Option C: systemd path unit as deployer
- [-] #selfdeploy.mainonly: runtimeBundle on main only
- [-] #selfdeploy.temurin: Temurin baked into the rootfs
- [~] #security: Security and privacy
- [^] Security audit: bindAddress 127.0.0.1, control token not in pages (M)
" v0.9.9, v0.9.10
- [^] robots.txt served by Werkator (XS)
" PR#25, merged as PR#26
- [^] Token-dependent responses never cached (S)
" PR#45
- [^] Private repositories obscured; metadata, not content (M)
" PR#43; PR#54, RFC 0003 D8
- [^] Six audit findings fixed (L)
" PR#55: CSP sandbox, symlink containment, read-only checkout, log names, socket opt-in, shape check.
- [x] Links between artifacts of a private repository (XS)
" PR#164: control-token cookie SameSite=Lax, artifacts stay sandboxed.
- [x] Build variables off the command line of werkdock and docker (S)
" PR#166: bare -e KEY, the value in the CLI's environment; werkdock PR#17 keeps it off bwrap's.
- [?] Real UI authentication (L)
" Needs an ADR that revises ADR 0004.
- [-] #security.login: Pages behind a login
- [-] #security.robotsinit: robots.txt generated by init
- [~] #ops: Deployment and operations
- [^] init --systemd user unit (M)
" Plan step 12, ADR 0004
- [^] Managed nginx/TLS container, opt-in (L)
" Plan step 13, ADR 0005, PR#124
- [^] jlink runtime bundle (M)
" Plan step 15, ADR 0006
- [^] Rename GitTally to Werkator (L)
" PR#1, v1.0.0
- [^] tools/remote: any host layout, authenticated clone, SSH multiplexing (M)
" PR#18, PR#21, PR#24, PR#28
- [^] Unit declares SuccessExitStatus=143 (XS)
" PR#73
- [ ] Bring vm4006 from v1.37.12 to main (S)
" Needs init --systemd once; remove TESTCONTAINERS_HOST_OVERRIDE.
- [-] #ops.spa: SPA or server push
- [-] #ops.compose: External compose stack instead of managed nginx
- [-] #ops.graal: GraalVM native image
- [-] #ops.container: Containerized Werkator runtime
- [~] #forgejo: Forgejo compatibility
- [^] ADR 0010, RFC 0006, export:forgejo and tools/werkator-to-forgejo (M)
" PR#92
- [^] Export notes by topic; job as header and steps (S)
" PR#115
- [ ] RFC 0006 step 2 rest: GITHUB_* and FORGEJO_* variables in every build (S)
" PR#92
- [ ] #forgejo.s3: RFC 0006 step 3: cheap deviations, one PR each (M) :#watch.list
- [ ] #forgejo.s3b: RFC 0006 step 3b: build environments as registry images (M)
- [ ] #forgejo.s4: RFC 0006 step 4: decide the deviations that stay (S)
- [ ] #forgejo.s5: RFC 0006 step 5: Werkator reads the workflow subset (L) :#forgejo.s3,#forgejo.s3b,#forgejo.s4
- [ ] #forgejo.s6: RFC 0006 step 6: one workflow on both systems in production (M) :#forgejo.s5
- [?] Workflow as the primary format, by a new ADR (XL)
- [-] #forgejo.free: Keep the own format free
- [-] #forgejo.replace: Replace the own format by the workflow format now
- [~] #tests: Tests, mutation testing and Mutation-CRAP
- [^] Kotest, MockK, WireMock, Testcontainers (S)
" ADR 0001
- [^] Flaky tests fixed (S)
" PR#20, PR#46, PR#60, PR#97, PR#157
- [^] unitTest and integrationTest tasks by spec name (S)
" PR#91
- [^] Nightly mutation build with Mutation-CRAP (M)
" PR#93, PR#94
- [^] Target 15, red from 12, gate as a ratchet (S)
" PR#104
- [^] Mutation-CRAP campaign, gate 650 to 15 (XL)
" PR#105 to PR#131
- [^] PIT memory and faster mutation tests (M)
" PR#134 to PR#145
- [^] PIT minions on the toolchain's JVM (S)
" PR#154; since PR#152 they ran on Gradle's Java 21 and found no test.
- [^] No endless loop for a mutant in the history's gap filler (XS)
" PR#162; HistoryTier.nulls gave MEMORY_ERROR, an inconclusive gate.
- [ ] Mutation tests in every build (L)
" Incremental on branches, full on main; the speed steps are done.
" The split, seeded from the history.bin of main, is still to be designed.
- [ ] Measured heap limit for PIT minions (S)
" PR#135, PR#136
- [-] #tests.frameworks: JUnit 5 or Spek 2
- [-] #tests.executorit: BuildExecutorIntegrationTest inside PIT
- [-] #tests.xmx512: PIT minions at -Xmx512m
- [-] #tests.origin: Version check against origin/main
- [~] #process: Development process and docs
- [^] A version per PR, checked by ReleaseVersionConsistencyUnitTest (S)
" PR#52
- [^] docs/llms.md (S)
" PR#36
- [^] Agents open PRs as WIP; AI review by werkrevisor; shared agentic workflow (S)
" PR#127, PR#128, PR#148
- [^] Werkbaum plan (S)
" PR#149
- [^] Codex review by the runner of werkrevisor, advise only (XS)
" PR#153
- [x] Codex review holds the merge (XS)
" PR#158; ai-review/codex is a required status.
- [x] A misreported build status waits for the human (XS)
" PR#159: Jev category status_misreported; BuildSettingsSource is a hard path.
- [x] docs/agentic-workflow.md from the master copy of werkregie (XS)
" PR#161
- [^] The AI review skips generated sections of the docs (XS)
" PR#165, after werkrevisor PR#122.
- [?] CI check that llms.md stays in sync (XS)
" PR#36
---
#sandbox.proot
ADR 0008: proot and fakechroot are slow and fragile, and they isolate nothing.
#sandbox.native
ADR 0008: native builds with hand-installed toolchains give no isolation.
#sandbox.levels
Level 2 pulls OCI images, level 3 offers a daemon API.
Deferred indefinitely on 2026-09-01; see plan step 21.
#sandbox.alias
The alias bwrap goes with plan step 18, which sets ConfigVersions.FORMAT_BROKE_IN.
#config.step18
The legacy branches section is read only while no build is defined.
When it is removed, FORMAT_BROKE_IN is set, and a leftover branches key is rejected by name.
#config.gittally
The fallback to the old name rides on plan step 18, like the bwrap alias.
#config.autobuild
ADR 0007: an autoBuild slot is a job in disguise.
#config.parallel
ADR 0007: autoBuild and builds in parallel forever are two ways to say one thing.
#config.pinbuilds
Reverted on 2026-08-29: a branch must describe its own CI (ADR 0007).
#config.maxconc
ADR 0007: the key moved to executor.maxConcurrent, without an alias.
#config.secrets
PR#51: too much machinery for two keys.
#watch.list
The list form is the counterpart of needs in a workflow; it is part of RFC 0006 step 3.
#multi.federation
ADR 0009: a dashboard over single-repository instances keeps N services and N ports.
#multi.prefix
Plan step 22: not needed, and it renames existing directories.
#ui.rfc0001
Option G, "Kin", replaced the options A to F.
#ui.trendbranch
Plan step 20 was revised to one trend per build definition.
#restart2
One restart repeats the build at the same commit, the other builds the newest commit of the branch.
A follow-up build and a pull-request target build run at a given commit, so they refuse the newest commit.
#artifacts.sqlite
ADR 0004: not needed; the repository interface keeps the switch possible.
#metrics.a2
RFC 0002: the cards may not grow.
#metrics.b2
RFC 0002: a second card doubles the cards.
#metrics.switch
PR#16: a choice that nobody makes.
#selfdeploy.pathunit
RFC 0005: not needed once restartsInstance exists.
#selfdeploy.mainonly
PR#61: changes to the deployment would be untestable before the merge.
#selfdeploy.temurin
PR#62: each Java update would mean about 1 GB uploaded by hand.
#security.login
Security audit: public read access is a requirement.
#security.robotsinit
PR#25: when Werkator serves robots.txt itself, it covers Apache and nginx.
#ops.spa
ADR 0004: polling is enough.
#ops.compose
ADR 0005: an external compose stack is manual work for every operator.
#ops.graal
ADR 0006: Spring AOT cannot hold CLI mode and server mode in one image.
#ops.container
ADR 0006: socket mounts, a HOME at the same path and uid mapping.
#forgejo.s3
Includes afterSuccessOf as a list.
#forgejo.free
ADR 0010: the own format stays expressible as a workflow.
#forgejo.replace
ADR 0010: the workflow format needs uses:, expressions and matrix; Werkator would be a second runner.
#tests.frameworks
ADR 0001: Kotest is more idiomatic; Spek has stalled.
#tests.executorit
PR#97: about one more hour per run.
#tests.xmx512
PR#134 gave MEMORY_ERROR; PR#135 reverted it.
#tests.origin
PR#52: it fails every branch that is merely out of date.