# Stacked-branch integration gate with mandatory GitHub CI

Use when several dependent feature/sprint branches must enter `main` through one PR while preserving the original commits.

## Provenance gate

1. Fetch `origin` before evaluating ancestry.
2. Record exact local and remote tips for `main` and every stacked branch.
3. For each adjacent pair, require `git merge-base --is-ancestor <parent> <child>` and record the merge base.
4. Inspect the complete first-parent path from `origin/main` to the final stack tip. A named sprint tip alone is not enough; intermediate baseline commits may also be part of the PR.
5. Review `git diff --name-status origin/main...<tip>`, untracked files, large blobs, forbidden DB/export/runtime extensions, secret patterns, and `git diff --check`.
6. If `origin/main` is not an ancestor, ancestry is ambiguous, or a real conflict exists, stop before branch creation or merge.

Create the integration branch from the exact final stack commit; do not mutate the completed sprint branch. CI-only integration commits may follow, but must keep the final sprint tip as an ancestor.

## Mandatory workflow authorization

A token that can fetch or push ordinary source files may still be forbidden from changing `.github/workflows/*`.

Before finalizing a constrained integration commit that includes a workflow, verify workflow-write permission against the exact repository when policy permits. GitHub permission evidence is behavioral:

- classic PAT: `repo` plus `workflow`;
- fine-grained PAT: Contents and Pull requests write, plus Workflows read/write; Actions read may be separately required to inspect runs;
- an empty `X-OAuth-Scopes` header from a fine-grained PAT proves nothing.

If the workflow push is rejected and automatic PR-CI is mandatory, keep the local branch and commit intact and stop. Do not move the workflow to documentation or publish a partial branch, because that silently violates the required gate.

Use a temporary `GIT_ASKPASS` reader for a canonical token file; never place the token in the remote URL, process arguments, logs, hashes, or evidence. **`GIT_ASKPASS` is only consulted when Git decides to prompt, so it does not override a cached/global credential helper by itself.** For canonical-file verification and workflow pushes, explicitly bypass stale helpers with `git -c credential.helper= ...`, keep `GIT_TERMINAL_PROMPT=0`, and remove the helper afterward. Do not print a token fingerprint as proof of rotation or permission: fine-grained permissions can change server-side while the token string stays identical. Verify owner/repository and authorization behaviorally.

## CI structure

For mixed Python/Vue repositories, split independent jobs while preserving required evidence:

- one uninterrupted full backend test invocation with an asserted expected test count;
- locked frontend install, full tests, TypeScript check, and production build;
- quality/contracts: Ruff on the governed surfaces, Compileall, migration probes, focused OpenAPI/auth/write/idempotency/reconciliation/performance controls, repository safety scan, and `git diff --check`.

All test/runtime/DB paths must be explicit runner-owned temporary paths. Include a fail-closed negative test for known production paths. Migration evidence should cover an empty DB and a synthetic previous-schema DB, compare seeded logical data before/after, run `integrity_check`, and assert ingestion/audit tables remain empty.

If `npm ci` or the production build reports dependency advisories, run `npm audit --omit=dev --json` read-only and classify package, direct/transitive status, affected platform/runtime, fix availability, and whether the lockfile changed in the integration diff. Do not hide advisories behind a green secret scan. A newly introduced exploitable high/critical finding is a security stop; an unchanged platform-inapplicable or build-only advisory is explicit inherited debt, not a fabricated clean bill of health.

## PR, merge, and deployment sequence

1. Push and verify the exact integration remote ref.
2. Open one PR to `main` with the complete commit chain, schema/security contracts, tests, prior incident/remediation, deployment evidence, and rollback target.
3. Wait for every required job to succeed; independently verify mergeability, diff, and ancestry.
4. Merge without squash or rebase so the stacked commits remain reachable.
5. Fetch and prove the exact remote-main SHA contains every expected stack commit; verify no unrelated branch changed.
6. Deploy exactly that verified remote-main commit, not a merely equivalent local tree.
7. Before restart, take and verify a consistent SQLite backup, schema/integrity, logical digest, and row counts. After restart, repeat logical evidence and assert no automatic ingestion.
8. Keep backend loopback-only and expose the frontend only through the approved private network/proxy. Verify health, proxy, responsive views, browser console, DNS name, and IP fallback.

A failed CI job, unclear ancestry, merge conflict, or security-relevant production delta is a real stop condition; ordinary progress messages are not.
