📝 docs(ci): design scoped tsl playbook sync
This commit is contained in:
@@ -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.
|
||||||
Reference in New Issue
Block a user