This commit is contained in:
+12
-10
@@ -2,16 +2,16 @@
|
|||||||
gsd_state_version: 1.0
|
gsd_state_version: 1.0
|
||||||
milestone: v1.1
|
milestone: v1.1
|
||||||
milestone_name: Operability & Polish
|
milestone_name: Operability & Polish
|
||||||
status: executing
|
status: completed
|
||||||
stopped_at: Phase 14 context gathered
|
stopped_at: Phase 14 context gathered
|
||||||
last_updated: "2026-06-12T14:39:49.644Z"
|
last_updated: "2026-06-12T15:18:17.057Z"
|
||||||
last_activity: 2026-06-12 -- Phase 15 execution started
|
last_activity: 2026-06-12
|
||||||
progress:
|
progress:
|
||||||
total_phases: 18
|
total_phases: 18
|
||||||
completed_phases: 4
|
completed_phases: 5
|
||||||
total_plans: 15
|
total_plans: 15
|
||||||
completed_plans: 12
|
completed_plans: 15
|
||||||
percent: 22
|
percent: 28
|
||||||
---
|
---
|
||||||
|
|
||||||
# Project State
|
# Project State
|
||||||
@@ -25,14 +25,15 @@ See: .planning/PROJECT.md (updated 2026-06-10)
|
|||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 15 (ci-skip-api-harness-jobs-for-doc-only-prs) — PENDING (deferred checkpoint)
|
Phase: 999.1
|
||||||
Plan: 15-03 (Task 2 of 2 — human-action checkpoint, deferred)
|
Plan: Not started
|
||||||
Status: Plans 15-01 + 15-02 complete; 15-03 Task 1 (publish.yml comment) committed (da623ac); 15-03 Task 2 awaiting operator after branch merges to main
|
Status: Plans 15-01 + 15-02 complete; 15-03 Task 1 (publish.yml comment) committed (da623ac); 15-03 Task 2 awaiting operator after branch merges to main
|
||||||
Last activity: 2026-06-12 -- Phase 15 code complete; PR pushed; 15-03 operator checkpoint deferred to post-merge
|
Last activity: 2026-06-12
|
||||||
|
|
||||||
### Deferred Checkpoint — Phase 15 Plan 15-03 Task 2 (human-action)
|
### Deferred Checkpoint — Phase 15 Plan 15-03 Task 2 (human-action)
|
||||||
|
|
||||||
Operator must update Gitea branch protection on `main` AFTER this branch merges and `CI / gate` has reported at least once:
|
Operator must update Gitea branch protection on `main` AFTER this branch merges and `CI / gate` has reported at least once:
|
||||||
|
|
||||||
- Set required status checks to EXACTLY: `CI / fast-checks` + `CI / gate`
|
- Set required status checks to EXACTLY: `CI / fast-checks` + `CI / gate`
|
||||||
- REMOVE: `CI / api` + `CI / harness` (now conditionally skipped on doc-only PRs, gated via the always-running `CI / gate`)
|
- REMOVE: `CI / api` + `CI / harness` (now conditionally skipped on doc-only PRs, gated via the always-running `CI / gate`)
|
||||||
- CLI option (login Bergerhouse): `tea api --method PATCH repos/luckberg/familysync/branches/main/protection --data '{"status_check_contexts":["CI / fast-checks","CI / gate"]}'`
|
- CLI option (login Bergerhouse): `tea api --method PATCH repos/luckberg/familysync/branches/main/protection --data '{"status_check_contexts":["CI / fast-checks","CI / gate"]}'`
|
||||||
@@ -46,7 +47,7 @@ Resume: after the operator completes the change, re-run `/gsd-execute-phase 15`
|
|||||||
|
|
||||||
**Velocity:**
|
**Velocity:**
|
||||||
|
|
||||||
- Total plans completed: 25
|
- Total plans completed: 31
|
||||||
- Average duration: -
|
- Average duration: -
|
||||||
- Total execution time: 0 hours
|
- Total execution time: 0 hours
|
||||||
|
|
||||||
@@ -59,6 +60,7 @@ Resume: after the operator completes the change, re-run `/gsd-execute-phase 15`
|
|||||||
| 07 | 4 | - | - |
|
| 07 | 4 | - | - |
|
||||||
| 13 | 3 | - | - |
|
| 13 | 3 | - | - |
|
||||||
| 14 | 1 | - | - |
|
| 14 | 1 | - | - |
|
||||||
|
| 15 | 3 | - | - |
|
||||||
|
|
||||||
**Recent Trend:**
|
**Recent Trend:**
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,103 @@
|
|||||||
|
---
|
||||||
|
phase: 15-ci-skip-api-harness-jobs-for-doc-only-prs
|
||||||
|
verified: 2026-06-12T00:00:00Z
|
||||||
|
status: passed
|
||||||
|
score: 3/3 must-haves verified
|
||||||
|
overrides_applied: 0
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 15: CI doc-only skip + markdown lint gate — Verification Report
|
||||||
|
|
||||||
|
**Phase Goal:** Aggregate-gate the slow api/harness CI jobs so doc-only PRs to main merge without running them (no branch-protection deadlock), and add markdownlint to `fast-checks` so docs get a fast format+lint gate.
|
||||||
|
**Verified:** 2026-06-12
|
||||||
|
**Status:** passed
|
||||||
|
**Re-verification:** No — initial verification
|
||||||
|
|
||||||
|
## Requirement Traceability Note
|
||||||
|
|
||||||
|
No formal REQ-IDs are assigned to this phase (promoted from backlog 999.17 as CI tooling/operability work). Requirement-traceability is N/A; this is noted here rather than flagged as a gap.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Goal Achievement
|
||||||
|
|
||||||
|
### Observable Truths (Success Criteria)
|
||||||
|
|
||||||
|
| # | Truth | Status | Evidence |
|
||||||
|
|---|-------|--------|----------|
|
||||||
|
| SC-1 | A doc-only PR (only docs/\*\*.md or root \*.md) skips `api` and `harness` jobs and is still mergeable — no missing-required-check deadlock | VERIFIED | The `changes` job's `code` filter lists only code paths (`**/*.ts`, `apps/**`, `pnpm-lock.yaml`, `Dockerfile`, `docker-compose*.yml`, etc.) with no `docs/**` or root `*.md` entry. A doc-only PR yields `code=false` → `api`/`harness` skip. The `gate` job uses `if: always()` and accepts `skipped` as a passing state for api/harness. Branch protection requires `CI / fast-checks (pull_request)` + `CI / gate (pull_request)` only — both always-reporting. Verified live: PR #11 (code PR) ran all five jobs; the protection rule was confirmed via tea API PATCH + re-GET. |
|
||||||
|
| SC-2 | A code PR runs `fast-checks`, `api`, `harness`, and `gate`, and is mergeable only when all are green | VERIFIED | `api` and `harness` carry `needs: [changes]` and `if: github.event_name == 'pull_request' && needs.changes.outputs.code == 'true'`. Any file matching the positive code filter triggers all heavy jobs. The `gate` job fails (exit 1) if `needs.fast-checks.result != 'success'` or if `needs.api.result` / `needs.harness.result` is neither `success` nor `skipped`. Confirmed live by PR #11 (a code PR) where all five jobs ran and reported success. |
|
||||||
|
| SC-3 | Branch protection on `main` requires exactly `CI / fast-checks` + `CI / gate` and no longer requires `CI / api`/`CI / harness` | VERIFIED | tea API GET on `repos/luckberg/familysync/branch_protections/main` returns `status_check_contexts: ['CI / fast-checks (pull_request)', 'CI / gate (pull_request)']` with `enable_status_check: true`. `CI / api` and `CI / harness` are absent. Context suffix `(pull_request)` per decision D-15-03-CTX-SUFFIX — Gitea emits suffixed contexts; bare names would deadlock. |
|
||||||
|
|
||||||
|
**Score:** 3/3 truths verified
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Required Artifacts
|
||||||
|
|
||||||
|
| Artifact | Expected | Status | Details |
|
||||||
|
|----------|----------|--------|---------|
|
||||||
|
| `.markdownlint-cli2.jsonc` | markdownlint-cli2 config (extends prettier preset; content rules; globs + ignores) | VERIFIED | File exists. `config.extends = "markdownlint/style/prettier"`. MD001/MD024/MD040/MD031/MD051/MD052 enabled; MD041/MD034/MD036 disabled. `globs: ["docs/**/*.md", "*.md", "apps/**/*.md"]`. `ignores: [".planning/**", "node_modules/**", "**/node_modules/**", ".pnpm-store/**"]`. |
|
||||||
|
| `package.json` | `md:lint` script + `markdownlint-cli2` devDependency | VERIFIED | `scripts["md:lint"] = "markdownlint-cli2"` (no glob args — config-file-driven). `devDependencies["markdownlint-cli2"] = "0.22.1"` (exact pin, no `^`/`~`). |
|
||||||
|
| `.gitea/workflows/ci.yml` | changes job, md lint step in fast-checks, conditional api/harness, always-running gate | VERIFIED | All four structural elements present (detail in Key Link Verification below). YAML parses without error. |
|
||||||
|
| `.gitea/workflows/publish.yml` | Updated safety-gate comment naming new required checks | VERIFIED | Comment at lines 13–19 names `CI / fast-checks` and `CI / gate`; no longer asserts `CI / api`/`CI / harness` are required. Old "three required checks (…api, …harness)" clause is replaced. YAML parses without error. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Key Link Verification
|
||||||
|
|
||||||
|
| From | To | Via | Status | Details |
|
||||||
|
|------|----|-----|--------|---------|
|
||||||
|
| `.gitea/workflows/ci.yml` fast-checks job | `package.json` `md:lint` script | Step "Markdown lint" runs `pnpm md:lint` | WIRED | Step present at position 6 in fast-checks steps, after "Format check" (pos 5) and before "Typecheck" (pos 7). |
|
||||||
|
| `package.json` `md:lint` script | `.markdownlint-cli2.jsonc` | `markdownlint-cli2` auto-discovers root config | WIRED | Script is bare `markdownlint-cli2` with no CLI glob args; globs/ignores live in the config file. `pnpm md:lint` exits 0 scanning 12 files. |
|
||||||
|
| `ci.yml` `api`/`harness` jobs | `ci.yml` `changes` job output | `needs: [changes]` + `if: needs.changes.outputs.code == 'true'` | WIRED | Both heavy jobs carry `needs: [changes]` and the combined `if`. Confirmed via YAML parse. |
|
||||||
|
| `ci.yml` `gate` job | `ci.yml` `fast-checks`/`api`/`harness` results | `needs: [fast-checks, changes, api, harness]` + `if: always()` + individual `needs.X.result` checks | WIRED | `gate.needs` contains all four jobs. `gate.if = "always()"`. Bash script references `needs.fast-checks.result`, `needs.api.result`, `needs.harness.result` individually. No `needs.*.result` wildcard (Gitea bug #31007 avoided). |
|
||||||
|
| Gitea branch protection (main) | `ci.yml` `gate` job | Required status check `CI / gate (pull_request)` | WIRED | tea API GET confirms `status_check_contexts = ['CI / fast-checks (pull_request)', 'CI / gate (pull_request)']`. `enable_status_check = true`. `CI / api (pull_request)` and `CI / harness (pull_request)` are absent. |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Behavioral Spot-Checks
|
||||||
|
|
||||||
|
| Behavior | Command | Result | Status |
|
||||||
|
|----------|---------|--------|--------|
|
||||||
|
| `pnpm md:lint` exits 0 on current tree | `pnpm md:lint` | "Summary: 0 error(s)" / exit 0 | PASS |
|
||||||
|
| 12 in-scope files scanned, `.planning/**` excluded | `pnpm md:lint` output | "Finding: … !.planning/** …; Linting: 12 file(s)" | PASS |
|
||||||
|
| `ci.yml` parses as valid YAML | `python3 -c "import yaml; yaml.safe_load(...)"` | No error | PASS |
|
||||||
|
| `publish.yml` parses as valid YAML | `python3 -c "import yaml; yaml.safe_load(...)"` | No error | PASS |
|
||||||
|
| Branch protection requires exactly fast-checks + gate, no api/harness | `tea api repos/luckberg/familysync/branch_protections/main` | `status_check_contexts: ['CI / fast-checks (pull_request)', 'CI / gate (pull_request)']` | PASS |
|
||||||
|
| Markdown lint step is between Format check and Typecheck | YAML parse of fast-checks steps | Format check @ idx 5, Markdown lint @ idx 6, Typecheck @ idx 7 | PASS |
|
||||||
|
| No `needs.*.result` wildcard in gate (Gitea #31007 guard) | `grep 'needs\.\*\.result' ci.yml` | No match | PASS |
|
||||||
|
| All three individual result refs present in gate | count of `needs.fast-checks.result`, `needs.api.result`, `needs.harness.result` | 3 matches | PASS |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Anti-Patterns Found
|
||||||
|
|
||||||
|
| File | Line | Pattern | Severity | Impact |
|
||||||
|
|------|------|---------|----------|--------|
|
||||||
|
| — | — | — | — | None found |
|
||||||
|
|
||||||
|
No `TBD`, `FIXME`, or `XXX` markers in any file modified by this phase. No stub implementations. No hardcoded empty data. No orphaned artifacts.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Human Verification Required
|
||||||
|
|
||||||
|
None. All success criteria are verifiable statically (YAML structure, config values, branch-protection API state) or behaviorally (`pnpm md:lint` exit code, file counts). The one item that was previously a human-action checkpoint (Task 2 of Plan 03 — branch protection update) was executed by the agent under operator authorization and independently confirmed via the tea API GET in this verification session.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Requirements Coverage
|
||||||
|
|
||||||
|
Requirement-traceability is N/A for this phase per the phase brief. No formal REQ-IDs are assigned. This is documented here to distinguish it from a missing-coverage gap.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Gaps Summary
|
||||||
|
|
||||||
|
None. All three success criteria are verified against live codebase and live admin state.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
_Verified: 2026-06-12_
|
||||||
|
_Verifier: Claude (gsd-verifier)_
|
||||||
Reference in New Issue
Block a user