phase: 135_git_source_branch
Build and Push Containers / build-and-push-app (push) Successful in 2m34s
Build and Push Containers / build-and-push-db (push) Successful in 14s

All verification complete. No edits were needed by this pass — the phase work and docs were already consistent and green.

**Phase 135 final verification pass — report**

- Verified all 5 tasks' work present & correct: migration 0024 (reversible), `GitSource.branch` + 4 schema shapes, `validate_branch_name` (full check order per design), `clone_or_pull(…, branch)` (HEAD guard first, `--branch` clone, fetch+ff merge), both call sites pass `row.branch`, UI (add-form field, editor field, row tag), `file://` URL transport.
- Completion criteria: (1) branch-mirrored through Sync + CLI — **pass** (E2E + integration); (2) `branch=None` byte-identical — **pass** (`test_branch_none_argv_is_byte_identical_pre_phase_sequence` green); (3) fixed 422s / local-row 422 / tri-state — **pass**; (4) mismatch fails loudly with remove-and-re-add — **pass** (E2E); (5) coverage 99% >90%, E2E isolated green — **pass**; (6) no regressions — **pass**.
- Tests: `uv run pytest --cov=app --cov-report=term-missing` → 3223 passed, app/ 99%; `uv run pytest tests/e2e/test_git_source_branch.py -v --no-cov` → 4 passed (16.4 s); `uv run ruff check .` clean; `uv run pyright` → 0 errors, 0 warnings.
- Documentation: README.md reviewed in full — phase-135 branch section accurate; the phase's README diff also correctly fixed a pre-existing stale line (shallow `--depth 1` clone vs full-history, phase 107). Routes, env defaults, feature lists verified against code. AGENTS.md — all 10 rules + quick-reference verified (referenced tests, PLAN.md, phases dirs, commands all accurate). **Verified consistent — no changes needed.**
- No live-infrastructure changes (dev DB already running and healthy; no live steps in this phase).
- Next pending phase: `.agents/phases/todo/136_force_push_reset`.
This commit is contained in:
2026-09-28 21:15:03 -04:00
parent fcac876d40
commit d3f8c7f2c8
50 changed files with 3955 additions and 140 deletions
+32
View File
@@ -707,6 +707,22 @@
placeholder="https://github.com/you/your-repo.git"
required
>
<!-- Phase 135 (task 04): the optional branch pin
(ASSUMPTION B6) — which branch of the repo the source
mirrors. BLANK = the POST omits the key (NULL = the
repo's DEFAULT branch — the pre-phase-135 clone/pull
behavior, byte-identical); a non-blank value is
validated server-side (validate_branch_name — the
fixed-detail 422 never echoes the input). -->
<label for="git-source-branch">Branch <span class="field-hint">optional — default: the repo's default branch</span></label>
<input
id="git-source-branch"
name="branch"
type="text"
maxlength="200"
autocomplete="off"
placeholder="main, release/1.2, …"
>
<!-- Phase 121 (task 03, LOCKED A2): the optional masked
private-repo credential — type=password +
autocomplete=off (a PAT is not a site credential: no
@@ -877,6 +893,22 @@
<div class="ignore-editor-panel">
<h2 class="ignore-editor-title" id="ignore-editor-title">Source settings</h2>
<code class="ignore-editor-source" id="ignore-editor-source"></code>
<!-- Phase 135 (task 04): the per-row branch editor —
GIT rows only (git-sources.js hides the label +
input + hint for local rows — local rows are walked,
not cloned — and the save body omits the key; the
API's 422 is the backstop). Opens prefilled from the
stored value (the API reports branch on every git
row — unlike the token, there IS a field to read it
from). THE TRI-STATE ASYMMETRY: a git row's PATCH
body ALWAYS includes branch — an EMPTY save is the
deliberate CLEAR leg (NULL = the repo's default
branch), unlike the token's blank = keep. -->
<label class="ignore-editor-label" for="ignore-editor-branch">Branch</label>
<input id="ignore-editor-branch"
type="text" maxlength="200" autocomplete="off"
placeholder="(default branch)">
<p class="ignore-editor-branch-hint">Leave empty for the repo's default branch.</p>
<p class="ignore-editor-copy" id="ignore-editor-copy">
One path per line. A file is ignored when its path in the
source starts with any of these — <code>/my/files/</code>,