One job: prove exactly what will be upgraded and define the graph before mutation.
Nodes you own
Start every node from t3u node-brief --node <id>; it carries the contract, routes and budget.
| Node | Focus |
|---|---|
intake |
One project, one DDEV clone, one authorized dataset source; nothing mutated |
project-identity |
Checklist item 1; any mismatch is findings → identity-recovery |
dataset-freshness |
Checklist item 2; empty, stale or unapproved data is findings → data-recovery |
extension-inventory |
Checklist items 4–7; flagged R: a second verifier reviews the resolutions |
url-discovery |
Checklist item 3; a missing sitemap is findings → sitemap-recovery |
identity-recovery |
Correct the identity evidence; never "fix" the site to match an assumption |
data-recovery |
scripts/pull-live-dataset.mjs (read-only on the server): delete the local fileadmin first, then sync; snapshot before the import. A dataset usable only with named gaps (case-colliding or missing files, absent tables) closes findings |
dataset-acceptance-decision |
Name every gap and its effect on proof coverage, ask the owner, record the answer as an approval and cite it; pass (reviewed) re-runs dataset-freshness against the accepted gaps, blocked stops |
sitemap-recovery |
Diagnose only; not-applicable (reviewed) routes to degraded-discovery |
degraded-discovery |
Approved page-tree or crawl fallback with named coverage gaps |
db-health-intake |
Checklist item 14, after intake-join; flagged R: a verifier checks the group classification |
db-health-recovery |
Flagged A: replay only the owner-approved curated dbdoctor SQL in one transaction before Baseline A; pass re-runs db-health-intake |
The controller closes intake-join with your sealed manifests/feature-contracts.json.
The two database-health nodes are the bounded exception to read-only intake: a dev-only tool in its own commit, a probe inside its own restored and fingerprint-proven snapshot, and only owner-approved fixes before Baseline A (database health).
Worker protocol
Your input is the node brief. Write its evidence file, return one allowed outcome, and never run
node-open/node-close or edit run state. Details: graph runner.
Keep the evidence lean: about 120 lines of proof, earlier artifacts cited by path and hash, one probe
artifact; at the brief's forecast (15 minutes or less) or twice it, stop and return what is proven
plus the open question (lean profile).
Preconditions
typo3-upgrade-runinitialized the local run and selected one project.- Work is inside a local DDEV clone. No staging/live access or sync action is authorized.
- Read
../typo3-upgrade-run/references/recent-run-lessons.md.
Evidence checklist
-
Record repository root, canonical remote, branch, HEAD, dirty/untracked ownership, DDEV root/name, primary URL, database identity, and installed TYPO3 core. Refuse any mismatch. Record the live/staging database server version (
-- Server versionin the dump header) against the target floor, and re-checkgit statusafter typo3-consolecache:flush/extension:list, which writesettings.phpdefaults (known problems). -
Record database dump/source date, maximum
pagesandtt_contenttimestamps, table/row sentinels, fileadmin count/hash, and one known page/content/media sentinel. A reachable empty or wrong database is a finding, not a usable baseline. -
Inspect sites/languages/bases, sitemaps, robots/canonical behavior, page-tree fallback, golden paths, dynamic routes, backend entry point, and local mail/search services. Name uncovered routes.
-
Inventory every installed/local/abandoned extension and feature usage. Preserve exact output of:
ddev composer why-not typo3/cms-core "^14.3" ddev composer why-not php 8.5 ddev composer audit --locked --format=json -
Require one resolution strategy per v14 blocker; do not implement it here. Apply native tools first: inventory existing Core commands/wizards before proposing scripts or dependencies; new optional extensions need dated adoption, maintenance and compatibility evidence. Put the choice in existing node evidence.
-
Check
typo3/cms-redirectsandspooner/deployer-information. If absent, activate dependency resolution. Always activate the editor-rights verification branch for Redirects. -
Identify Mask/Content Blocks, Vite/assets, Solr/search, RTE/Visual Editor, Powermail/forms, scheduler, custom backend modules/rights, local extensions, and schema/data migrations. Read fleet regression contracts. Inventory actual mail/DOI/CAPTCHA entry points, tracking context/consent, cache dependencies, historical routes and persisted business records. Record applicability once, with representative journeys and named assertions in the feature plan.
-
Record credential origins without reading/printing values. Reject committed/hard-coded secrets, ambiguous origins, production sessions, or cross-origin credential flows as security findings. Inventory the env loader, jQuery/plugin dependencies and the live-sync helper without executing it. Plan their scoped modernization; read the orchestrator's project environment for the dotenv/config-handling distinction. Every Bootstrap site ends on the latest stable 5.x: inventory the Bootstrap version and its use, estimate a 3/4 → 5 migration, and ask the owner for the intent approval and a review slot, all per the migration intake.
-
Verify backup capability: artifact type, timestamp, checksum, target identity, restore command, and storage path. This is readiness evidence; take snapshots only immediately before stateful nodes.
-
Read
../typo3-upgrade-run/references/runtime-sizing.md. Record all nine sizing metrics and their source artifacts innodes/intake/runtime-size.json, with every TYPO3 14 blocker in its blocker inventory (dev-only, unused and drop-in packages are recorded, not counted); select no profile yourself. Lett3u runtime-sealcalculate and seal the smallest fitting small/large/huge profile. -
Produce risk/cost order, graph applicability outcomes, and a smallest-decision list for the user. Run the read-only TYPO3 14 fix-pack probe and record every item as present or not present. A dev-server render (item 9) is settled now, before the baseline. So are item 15's golden paths: a
strict(or unset) translated language with Extbase list plugins needs its translated list and detail URLs in Baseline A. -
Compare processed images live against local on one or two pages that show
csm_*images (read-only GETs on live):node skills/typo3-upgrade-run/scripts/gfx-colour-parity.mjs \ --live https://www.example.org/<page>/ --local https://<project>.ddev.site/<page>/Exit 1 means the local derivatives differ in colour from live, typically through another
GFXprocessor or colourspace: Baseline A would prove a wrong local render, and before and after stay equally wrong. Exit 3 means no pair was measured; pick another page. Settle a difference now like the dev-server render, as a DDEV-only environment decision recorded in the intake evidence: the processor of live, ImageMagick only withsRGB(image processing like production), thenddev typo3 cleanup:localprocessedfiles --all --force(12.4 lacks--all: Maintenance > Remove Temporary Assets),ddev typo3 cache:flushand the check again until it exits 0. Baseline A already sealed: never re-baseline. Fix DDEV in the next code node, regenerate the processed files, and declare the image difference to Baseline A as one owner-approved class with a before/after pair (rule 30.8). -
Ask every known decision in one question round before unattended execution: dataset, PHP, Lighthouse floors, Bootstrap/jQuery, extension removals, the fix-pack approvals, delegation and commits, and the scope of the two standard Contract B branches: structured data (at least Organization/WebSite, WebPage, BreadcrumbList, plus the eligible types found) and WebMCP (read-only navigation/lookup tools, prepare-only form tools, the Permissions-Policy decision). Ask which types and tools, never whether: both run in every upgrade. Forecast work from measured capture/test throughput as well as site size (fleet durations). Read
../typo3-upgrade-run/references/overnight-controller.md, write the selected-route runtime plan and runt3u graph-forecastbefore the baseline. A missing or non-fitting estimate blocks admission. The size-dependent 8/24/48h caps are not completion guarantees. -
Database health (
db-health-intake): install the pinnedlolli/dbdoctor(1.0.6 on a 12.4 source, the exact 2.2.x on 13.4) with--devin its own commit, runscripts/db-health.mjs check, thenprobefor the full(check, table, uid)inventory, and record version and runtime. Classify every group aspre-existingor owner-approved for a fix, following the round-1 policy (record only, or fix approved groups before Baseline A). Never approve the 1.0.6…ParentLanguageDifferentgroups, never let dbdoctorexecutea kept database (database health).
Routes
pass: identity, dated dataset decision, sites/URLs, blockers, credentials boundary, and graph applicability are evidenced.findings: route identity, dataset, sitemap/discovery, dependency, or credential issue to its specific recovery node.blocked: wrong/ambiguous project, secret exposure, no acceptable data, unsafe origin, or an unavailable decision prevents a safe run.
Output
Write node evidence under .typo3-update/nodes/ and manifests under .typo3-update/manifests/.
Include commands and exit codes, hashes, unresolved facts, approvals/ADRs needed, selected routes,
explicit non-applicable branches, and the runtime-sizing evidence. Do not say “ready” when any
identity, dataset, or sizing field is inferred.
For a new default graph, close intake-join with manifests/feature-contracts.json as its evidence.
This hash-sealed plan reuses inventory artifacts; it does not introduce extra browser passes.
Boundaries
Use typo3-upgrade-baseline for deterministic capture, typo3-upgrade-migration for changes, and
typo3-upgrade-retrospective when reconstructing an old run. Use typo3-ddev for DDEV mechanics,
but keep this skill responsible for the upgrade-specific identity verdict.