diff --git a/docs/superpowers/specs/2026-07-13-sync-tsl-playbook-workflow-upgrade-design.md b/docs/superpowers/specs/2026-07-13-sync-tsl-playbook-workflow-upgrade-design.md new file mode 100644 index 00000000..d440a615 --- /dev/null +++ b/docs/superpowers/specs/2026-07-13-sync-tsl-playbook-workflow-upgrade-design.md @@ -0,0 +1,116 @@ +# Sync TSL Playbook Workflow Upgrade Design + +## Background + +The `tsl-playbook` branch is a mixed branch: the synchronization workflow owns the +generated TSL playbook paths, while README files and other manually maintained +content must survive each publication. + +The current workflow treats the whole `docs/` and `skills/` directories as generated: + +```bash +generated_paths=(AGENTS.md docs skills) +``` + +That ownership boundary is wider than the bundle actually owns. TSL syntax is now +provided by `tsl-syntax-reference`, while the branch may also contain unrelated +documentation and Skills that the workflow must not delete. + +## Goal + +Redesign `.gitea/workflows/sync-tsl-playbook.yml` so it updates only the TSL +playbook paths while preserving every unrelated target-branch file. + +## Managed Paths + +The workflow exclusively owns these four paths: + +```text +AGENTS.md +docs/tsl/ +skills/tsl-syntax-reference/ +skills/tsl-api-reference/ +``` + +It must preserve all other paths, including: + +- root files such as `README.md`; +- non-TSL documentation under `docs/`; +- unrelated Skills under `skills/`; +- any other manually maintained target-branch content. + +The workflow does not special-case `docs/tsl/syntax`. Whether that path exists is +determined by the source tree and the bundle builder, not by publication logic. + +## Publication Flow + +1. Clone and check out the latest `origin/main` in a temporary repository. +2. Build the TSL bundle outside the repository working tree. +3. Validate that all four managed paths exist in the bundle. +4. Check out the existing remote target branch, or create an orphan target branch. +5. Remove only the four managed paths from the target working tree. +6. Copy each managed path explicitly from the bundle. +7. Stage changes only for the four managed paths. +8. Exit successfully without a commit when the staged diff is empty. +9. Otherwise commit with the source SHA footer and push the target branch. + +Explicit copying is preferred over copying the bundle root. This keeps the workflow's +write behavior aligned with its declared ownership boundary even if the bundle gains +additional top-level files later. + +## Branch Behavior + +For an existing `tsl-playbook` branch, the workflow starts from +`origin/tsl-playbook`, so unmanaged files retain their current content and history. + +For a new target branch, the workflow creates an orphan branch and clears the inherited +index before adding the four managed paths. Source-only files from `main` must not leak +into the new branch. + +The workflow must not merge the source and target branches. It publishes a generated +commit directly on the target branch. + +## Failure Handling and Security + +- Missing bundle paths fail before the target branch is modified. +- `set -euo pipefail` remains enabled for shell steps. +- The bundle remains outside the repository so branch checkout cannot clobber it. +- Authentication continues through `GIT_ASKPASS`; credentials are never embedded in + the remote URL. +- Temporary bundle and askpass files are removed through existing cleanup paths. +- A failed copy or validation must prevent commit and push. + +## Test Strategy + +Update the workflow contract and integration tests before changing the workflow. + +The tests must demonstrate that: + +- the managed path list contains the four exact paths and not the broad `docs` or + `skills` directories; +- root files outside the managed set survive synchronization; +- non-TSL documentation under `docs/` survives synchronization; +- unrelated Skills under `skills/` survive synchronization; +- stale files inside each managed directory are deleted; +- a newly created target branch contains the bundle paths without source-branch + leakage; +- an unchanged bundle produces no commit; +- token handling remains based on `GIT_ASKPASS` and a credential-free repository URL. + +## Non-Goals + +- Do not change the contents of `AGENTS.md`, TSL documentation, or either TSL Skill. +- Do not add special handling for obsolete syntax-document paths. +- Do not redesign `scripts/build_tsl_playbook.py` unless a workflow test exposes an + interface mismatch required by the exact managed-path contract. +- Do not delete or rewrite unrelated files on the target branch. +- Do not change the target branch name or commit-message convention. + +## Acceptance Criteria + +- Publication changes are limited to the four managed paths. +- Unmanaged target-branch files are byte-for-byte preserved. +- Stale content inside managed paths is removed. +- New target branches contain no accidental files inherited from `main`. +- Existing workflow security assertions and sync integration tests pass. +- The full `test_build_tsl_playbook.py` suite passes.