Skip to main content

release

MUST READ before preparing a release commit or GitHub release -- the blocking GitHub preflight (dev/release_preflight.py), project.save() versioning, changelog, README, template sync verification, fresh-install smoke, and the post-push GitHub release procedure (references/github-release.md).

Quellinformationen

Repository
dylanroscover/Embody
Letzte Quellaktivität
26. September 2026 um 06:32
Erkannte Sprache von SKILL.md
Englisch
Sterne
182
Forks
11

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

Datei-Explorer
2 Dateien

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
release
description
MUST READ before preparing a release commit or GitHub release -- the blocking GitHub preflight (dev/release_preflight.py), project.save() versioning, changelog, README, template sync verification, fresh-install smoke, and the post-push GitHub release procedure (references/github-release.md).
# Release Commit Procedure When the user asks to prepare a release commit (e.g., "prep a commit for v217"), follow these steps in order. After a successful push, follow `references/github-release.md` for the GitHub release. ## Preflight: nothing outstanding on GitHub (blocking, before step 0) Run this from the release checkout (the repo root, on `dev`) before anything else, and again right before the push (`python3` on macOS): ``` python dev/release_preflight.py ``` - **BLOCKING:** open Dependabot, code-scanning or secret-scanning alerts; draft or triage security advisories (private vulnerability reports); open Dependabot PRs; a red latest push-CI run of any workflow on `main` or `dev`; a failed third-party check on either tip; real commits on `main` that the release checkout lacks (a hotfix never merged back: merge `origin/main` in and push). A check it cannot run also blocks, so a failed API call never reads as "nothing open". - **WARNING:** other open PRs, every open issue (tagged NEW since the last release), merged branches left on the remote. - **Exit 1 = STOP.** Show the user every item. Each blocker gets resolved (a Dependabot PR merged only after its platform e2e run is green, or closed; alerts fixed or dismissed with a reason; hotfixes back-merged) or the user explicitly accepts it. Only then re-run with `--ack "<key>"`, and only for keys the user named. Never ack on your own judgment. - **Report the warnings in the same message.** List any acked items in the release commit body so the decision is on record. Why: on 2026-09-11 embody.tools sign-in was down ~23h after a dependency bump (PR #105) and specimen submit had been broken 4 days by a rename; two hotfixes then sat on `main` without `dev`. The preflight keeps outstanding GitHub state from being skipped; the platform e2e gate is what catches a breaking bump. ## 0. Save the Project The entire save call is `project.save()` -- no arguments. TD increments the `.toe` filename's trailing build, the `onProjectPreSave` hook in `dev/embody/execute_src_ctrl.py` bumps `par.Version`, deletes the prior release `.tox`, and exports the new one. Filename and `par.Version` stay in lock-step. The release export honors `pre_release`/`post_release` hook DATs placed directly under the Embody COMP (none exist today; they fire on EVERY `project.save`, always in LIVE mode -- the Embody comp is never copy-staged, so such hooks would mutate the live comp). On any export failure the manifest is NOT written and the prior version's stale manifest is removed: a pre_release abort or save failure leaves NO release `.tox` for the new version, while a post_release failure leaves the fresh `.tox` WITHOUT a manifest -- check the log and `release/` before pushing. The self-updater's rollback backup export passes `run_hooks=False`, so shipped hooks never fire in user projects during updates. Don't pass a path (TD increments from *your* path's build, desyncing by one). Don't pre-set `par.Version`. Don't call `ExportPortableTox` directly. **If externalized files changed on disk while TD was closed** (e.g. a landed worktree diff), verify the affected DATs re-synced into the live network BEFORE saving: table DATs load their file only on the post-launch refresh sweep, which can run AFTER an early save -- and the portable export captures LIVE DAT state, shipping stale content (observed v6.0.133: the exported `palette_catalog` was missing all 267 just-landed 33070 rows). Pulse `op.Embody.par.Refresh` and spot-check the changed DATs (row counts, code markers), then save. If you've already mis-saved: rename the off-by-one `.toe` on disk to match `par.Version`, then have the user close TD without saving and reopen. Do **not** save again -- the hook will delete the just-correct release `.tox`. ## 1. Audit All Changes - Run `git diff --stat` and `git diff HEAD --name-status` to identify every changed, added, and deleted file. - Read the diffs for all core source files (EmbodyExt.py, TDXNExt.py, EnvoyExt.py, etc.) to understand what was fixed/added. - Read diffs for new test files to understand coverage additions. - Read diffs for docs, schema, and rule/skill files. ## 1b. Docs Audit: every change in this release is documented The changelog says a release HAPPENED; `docs/` is what users read to USE the thing. A feature or a behavior change that ships with only a changelog bullet is undocumented -- and the drift is invisible, because nothing fails. Walk the release diff (step 1) and, for EVERY user-visible change, name the `docs/` page that now describes it. Not "does a page exist" -- does the page say the new truth. | Change in the diff | Docs obligation | |---|---| | New feature, parameter, MCP tool, or Convoy operation | A section on its owning page, reachable from `mkdocs.yml` nav. A genuinely new subsystem gets its own page. | | Changed behavior (defaults, gating, retries, timeouts, statuses) | Update the page that states the OLD behavior. Grep the old wording -- it is usually in more than one place (a parameter row, a concept page, a troubleshooting row). | | New user-visible string (status text, dialog, error) | Add or fix its Troubleshooting row so a user who searches the literal text lands on the fix. | | Removed / retired feature, par, or tool | Delete or amend every page that still promises it. A stale promise is worse than a missing page. | | Parameter help text edited in TD | `docs/embody/parameters.md` mirrors par help -- keep them identical. | | Internal refactor with no user-visible effect | Nothing. Say so explicitly in the audit rather than skipping the question. | Mechanics: - `git diff HEAD --name-status` -> for each source file, ask what a USER could observe. If the answer is "nothing", write that down; if it is anything else, the docs edit is part of THIS release, not the next one. - Grep before you write: `grep -rn "<old behavior phrase>" docs/` finds the copies that would otherwise go stale. Fix all of them. - New page -> add it to `mkdocs.yml` nav, or it ships invisible. - `mkdocs build --strict` must pass (broken internal links are errors). It proves the page BUILDS; step 7 is what makes it PUBLISHED. - Docs written in this pass are part of the release commit, so the changelog bullet and the page land together. Report the audit as a short list -- "changed X -> documented at `docs/...`", "changed Y -> internal only" -- so a skipped obligation is visible rather than implied. ## 2. Update Changelog Add a new entry at the top of `docs/changelog.md`: ```markdown ## v5.0.XXX One-line summary of the release themes. - **Feature/fix name.** What changed, in 1-2 sentences. - ... ``` ### Length is a hard cap (standing user directive) **One line of theme. 3-5 bullets, one to two lines each. Under ~160 words.** Nobody reads a wall of bullets, and an exhaustive one reads as AI slop. Twelve changes still get <= 5 bullets: group by theme, and give the leftovers one combined **Fixes.** bullet rather than a bullet each. The detail lives in the commit log and the diff. But **too short is also wrong** -- do not drop a user-facing feature to make the count. A shipped tool, a new install path or a fixed crash each earn their line; only internals get cut. A small release can be one bullet (`v6.0.250` in `docs/changelog.md` is the model); a big one uses all five. **Unreleased intermediate versions fold into the published entry.** `project.save()` bumps the version on every save, so most numbers never ship. Consolidate the whole tag-to-tag range (`git log <lasttag>..HEAD`) into the one entry -- and never leave a shipped feature out of it because it landed under a version that was superseded. Always cut: - incident stories, repro narratives, root-cause retelling - internal mechanisms -- protocol shapes, private names, fallback ladders - a superseded version, beyond one short parenthetical - test counts, beyond `+N tests` folded into a bullet Then COUNT. Over 5 bullets or ~160 words, cut before shipping -- never ship long and offer to trim after. ## 3. Update README.md - **Version badge + minimum-build statements are AUTOMATED**: `project.save()` (via `execute_src_ctrl.updateVersionDocs`) rewrites the README version badge from `par.Version` and the minimum-TD-build lines in README.md, docs/index.md, and CONTRIBUTING.md from the running `app.build` (the build we save with IS the support floor). Verify they match rather than editing by hand; the `test_version_sync` suite fails on any drift. - **Release history**: Add a one-line entry at the top of the "Recent releases" list. - **Test suite count**: Update the count if new test files were added (count `dev/embody/unit_tests/test_*.py`). ## 4. Verify Template Sync **When updating a rule or skill in `.claude/`, also update the corresponding template DAT in `dev/embody/Embody/templates/` if one exists.** This applies on every edit, not just at release time -- drift between source and template ships stale guidance to user projects. Templates in `dev/embody/Embody/templates/` must stay in sync with their `.claude/` counterparts: | `.claude/` file | Template file | |---|---| | `rules/td-python.md` | `templates/text_rule_td_python.md` | | `rules/parameters.md` | `templates/text_rule_parameters.md` | | `rules/mcp-safety.md` | `templates/text_rule_mcp_safety.md` | | `rules/network-layout.md` | `templates/text_rule_network_layout.md` | | `rules/td-connectivity.md` | `templates/text_rule_td_connectivity.md` | | `rules/multi-session.md` | `templates/text_rule_multi_session.md` | | `rules/worktree-td-safety.md` | `templates/text_rule_worktree_td_safety.md` | | `rules/performance.md` | `templates/text_rule_performance.md` | | `rules/tdxn-economy.md` | `templates/text_rule_tdxn_economy.md` | | `skills/td-api-reference/SKILL.md` | `templates/text_skill_td_api_reference.md` | | `skills/movie-export/SKILL.md` | `templates/text_skill_movie_export.md` | | `skills/parameter-design/SKILL.md` | `templates/text_skill_parameter_design.md` | | `skills/td-recovery/SKILL.md` | `templates/text_skill_td_recovery.md` | | `skills/multi-session-etiquette/SKILL.md` | `templates/text_skill_multi_session_etiquette.md` | | `skills/create-operator/SKILL.md` | `templates/text_skill_create_operator.md` | | `skills/debug-operator/SKILL.md` | `templates/text_skill_debug_operator.md` | | `skills/externalize-operator/SKILL.md` | `templates/text_skill_externalize.md` | | `skills/create-extension/SKILL.md` | `templates/text_skill_create_extension.md` | | `skills/manage-annotations/SKILL.md` | `templates/text_skill_manage_annotations.md` | | `skills/mcp-tools-reference/SKILL.md` | `templates/text_skill_mcp_tools_reference.md` | | `skills/pop-networks/SKILL.md` | `templates/text_skill_pop_networks.md` | | `skills/visual-aesthetics/SKILL.md` | `templates/text_skill_visual_aesthetics.md` | | `skills/brief/SKILL.md` | `templates/text_skill_brief.md` | | `skills/merge-divergent-tox/SKILL.md` | `templates/text_skill_merge_divergent_tox.md` | | `skills/glsl-shaders/SKILL.md` | `templates/text_skill_glsl_shaders.md` | | `skills/operator-gotchas/SKILL.md` | `templates/text_skill_operator_gotchas.md` | | `skills/testing/SKILL.md` | `templates/text_skill_testing.md` | | `skills/collab/SKILL.md` | `templates/text_skill_collab.md` | | `skills/td-api-reference/references/background-work.md` | `templates/text_skill_td_api_reference__background_work.md` | | `skills/td-api-reference/references/heavy-build-safety.md` | `templates/text_skill_td_api_reference__heavy_build_safety.md` | | `skills/parameter-design/references/state-lifetimes.md` | `templates/text_skill_parameter_design__state_lifetimes.md` | | `skills/mcp-tools-reference/references/coordination.md` | `templates/text_skill_mcp_tools_reference__coordination.md` | | `skills/visual-aesthetics/references/craft.md` | `templates/text_skill_visual_aesthetics__craft.md` | | `skills/visual-aesthetics/references/look-recipes.md` | `templates/text_skill_visual_aesthetics__look_recipes.md` | | `skills/merge-divergent-tox/references/procedure.md` | `templates/text_skill_merge_divergent_tox__procedure.md` | This table is the source of truth for what ships; keep it in sync with `_TEMPLATE_MAP_RULES` / `_TEMPLATE_MAP_SKILLS` in `EmbodyExt.py` (the actual shipping map). Template files that exist on disk but are NOT in that map (e.g. `text_rule_commit_push_checklist.md`, `text_rule_github_release.md`, `text_rule_refresh_after_commit.py`) are orphans -- do not add them here. Templates should be UTF-8 with LF line endings and no BOM. Each template carries an Embody/Envoy generated-by HTML comment, and otherwise must match its `.claude/` counterpart in content -- diff them (normalizing any legacy BOM + line endings) and fix any drift. Dev-only rules and skills (e.g. `.claude/rules/commit-push-checklist.md`, `.claude/rules/skill-prerequisites.md`, `.claude/rules/code-brevity.md`, `.claude/rules/multi-agent-review.md`, `.claude/rules/destructive-tests.md`, `.claude/rules/embody-code-conventions.md`, `.claude/rules/refresh-after-commit.md`, `.claude/skills/release/` (this skill, incl. `references/github-release.md`), `.claude/skills/agent-tests/`, `.claude/skills/add-mcp-tool/`, `.claude/skills/run-tests/`) live under `.claude/` for Embody developers only and are NOT shipped to user projects -- they have no template counterpart. The root `CLAUDE.md` and `dev/embody/Embody/templates/text_claude.md` serve different audiences and are maintained independently. ## 4b. Re-Vendor the Convoy Host App The Convoy host-app daemon exists TWICE on purpose: the source of truth in `dev/convoy/`, and a vendored copy at `dev/embody/Embody/convoy/host/` carried inside the `.tox` as text DATs so that installing works with no network access. If the vendored copy is stale, the release ships an installer that writes an OLD daemon -- and nothing about the running project looks wrong. ``` python dev/convoy/vendor_host_modules.py --check # exit 1 = drift python dev/convoy/vendor_host_modules.py # re-vendor, then SAVE ``` The vendored DATs are `syncfile=True`, so copying the file is the whole re-vendor -- TD reloads the DAT on its own. **The new content only reaches the shipped `.tox` on the next `project.save()`**, so re-vendor BEFORE step 0's save, never after. `--check` reports four drift classes; only the first is fixed by copying: | Class | Meaning | Fix | |---|---|---| | `STALE` | content differs | re-vendor (this script) | | `MISSING` | daemon module has NO vendored DAT | create a text DAT of that name in the `host` COMP and externalize it (tag `py`) -- **a file copy alone does not make it ship** | | `ORPHAN` | vendored file with no daemon source | `delete_op` the DAT (deleting only the file lets the next save re-create it) | | `ok` | current | -- | `test_convoy_host_vendor.py` asserts the same thing on the CI matrix, comparing newline-normalized text (Embody writes CRLF on Windows; `.gitattributes` stores LF, so the committed bytes are identical). Do not "fix" a CRLF diff by changing how Embody writes files -- that path is shared by every externalized DAT in the project. Note `convoy_install.HOST_MODULES` is a hardcoded manifest and has gone stale twice already. It is not the gate; the parity test is. If you add a daemon module, the test tells you what else to do. ## 5. Fresh-Install Smoke (before the release commit) Cold-open smoke of the DEV project is not enough: a fresh install runs a different path (the shipped `.tox` in a virgin project -- `init()` lifecycle, baked par values, no dev checkout, no externalized files). The v6.0.145 empty-Update-Status miss shipped precisely because this step was skipped. Run it after step 0's save (it reads the manifest that save wrote), from the repo root -- one command, same on Windows and macOS: ``` dev/.venv-tests/Scripts/python.exe dev/release_testing/smoke_run.py
Auf GitHub ansehen
Diese SKILL.md ist sehr gross, daher zeigt SkillsMP hier nur den ersten Abschnitt. Auf GitHub ansehen