docs: handoff-80 + docs direct-push carve-out (ADR-0059 Amendment 1)
Session handoff covering the clause-concept-hints feature (ADR-0058, #42) and the working-method establishment (ADR-0059, #41; fixes #43/#44). Records the docs direct-push carve-out: handoff/session docs and small docs amendments are owner-direct-pushed to main, because a docs-only PR posts no ci/gate run (paths-ignored) and stalls on the required check. Amends CLAUDE.md, ADR-0059 (Amendment 1), and its README index row.
This commit is contained in:
@@ -303,6 +303,14 @@ operational rules an agent must follow:
|
|||||||
or merge.
|
or merge.
|
||||||
- **Paste the `/runda` / DA review into the PR** so the public repo carries
|
- **Paste the `/runda` / DA review into the PR** so the public repo carries
|
||||||
the audit trail.
|
the audit trail.
|
||||||
|
- **Handoff / session docs are owner-direct-pushed to `main`, not PR'd** (a
|
||||||
|
deliberate extension of the reservation-ledger carve-out). Reason: a
|
||||||
|
docs-only change is `paths-ignore`d by `ci.yaml`, so it posts no `ci / gate`
|
||||||
|
run — and branch protection *requires* `ci / gate*`, so a docs-only PR
|
||||||
|
stalls forever on a required check that never arrives. Direct-push (owner
|
||||||
|
is whitelisted, docs paths burn no CI) sidesteps that. The same applies to
|
||||||
|
small docs amendments like this one. If docs-via-PR is ever wanted, first
|
||||||
|
add a "skipped → success" gate shim (or drop the docs paths-ignore).
|
||||||
|
|
||||||
## Issue tracking — Gitea via `tea`
|
## Issue tracking — Gitea via `tea`
|
||||||
|
|
||||||
|
|||||||
@@ -190,3 +190,26 @@ test the script but not run its pushing path.
|
|||||||
- **Automating PR creation/merge** — humans push and merge (D6).
|
- **Automating PR creation/merge** — humans push and merge (D6).
|
||||||
- **A CONTRIBUTING-side description of the reserve lock** — it's maintainer
|
- **A CONTRIBUTING-side description of the reserve lock** — it's maintainer
|
||||||
infrastructure, not contributor guidance (kept here instead).
|
infrastructure, not contributor guidance (kept here instead).
|
||||||
|
|
||||||
|
## Amendment 1 (2026-06-25): docs direct-push carve-out
|
||||||
|
|
||||||
|
Extends the D5 owner-whitelist: **handoff / session docs (and small docs
|
||||||
|
amendments like this one) are owner-direct-pushed to `main`, not PR'd.**
|
||||||
|
|
||||||
|
Discovered while preparing the first handoff under this flow: a **docs-only
|
||||||
|
PR cannot merge** under the protection rules. `ci.yaml` `paths-ignore`s
|
||||||
|
`docs/**` and `**/*.md`, so a docs-only change posts **no `ci / gate` run**;
|
||||||
|
but D5 requires `ci / gate*` before merge — so the required check never
|
||||||
|
arrives and the PR stalls on "expected/waiting". Rather than weaken the gate
|
||||||
|
or add CI machinery, this trivial low-risk class (handoffs, session notes,
|
||||||
|
small docs fixes) rides the existing owner-direct-push carve-out: the owner
|
||||||
|
is already whitelisted, and a docs-only push to `main` is itself
|
||||||
|
`paths-ignore`d, so it burns no CI.
|
||||||
|
|
||||||
|
Substantive changes — code, and the ADRs/docs that accompany code — still go
|
||||||
|
through a PR as normal (their non-docs files trigger the gate). **If
|
||||||
|
docs-via-PR is ever wanted** (e.g. a docs-only ADR through review), the clean
|
||||||
|
fix is a "skipped → success" gate shim (a job that reports `ci / gate`
|
||||||
|
success when the real gate is path-skipped) or dropping the docs
|
||||||
|
`paths-ignore`; until then, direct-push is the sanctioned path for docs-only
|
||||||
|
changes.
|
||||||
|
|||||||
+1
-1
File diff suppressed because one or more lines are too long
@@ -0,0 +1,144 @@
|
|||||||
|
# Session handoff — 2026-06-25 (80)
|
||||||
|
|
||||||
|
A long session. It began as the next open-issue item — **#37, clause-concept
|
||||||
|
hints** — but the act of cutting a branch for it surfaced that this
|
||||||
|
now-public repo had **no written, trackable working method**. So the bulk of
|
||||||
|
the session became establishing one (**ADR-0059**) and hardening it through
|
||||||
|
real use, with two follow-up fixes the dogfooding turned up. Both arcs are
|
||||||
|
fully merged; the tree is clean.
|
||||||
|
|
||||||
|
## §1. State
|
||||||
|
|
||||||
|
**Branch `main` at `78272e2`.** Everything below is merged; **no open PRs**;
|
||||||
|
worktrees are just the primary (`main`) + the long-lived `website`. All
|
||||||
|
feature/fix worktrees were cleaned up with `wt-rm`.
|
||||||
|
|
||||||
|
**Suite green at #37's merge:** **1831 lib + 8 e2e_pty + 503 it + 200 typing
|
||||||
|
(2542 total), 0 failed, 1 ignored**; `fmt --check` + `clippy -D warnings`
|
||||||
|
clean (via `nix develop -c`). The new workflow scripts carry their own
|
||||||
|
local-`origin` harnesses: `test-adr-reserve.sh` **10/10**, `test-wt.sh`
|
||||||
|
**16/16**, all `shellcheck`-clean.
|
||||||
|
|
||||||
|
**Issues:** closed this session — **#37** (done, ADR-0058) and **#38**
|
||||||
|
(won't-do, see §4). Still open — **#40** (winget release notes, deferred to
|
||||||
|
next release; see §4). (#36/#39 were closed in earlier sessions.)
|
||||||
|
|
||||||
|
## §2. What shipped — #37 clause-concept hints (ADR-0058, merged #42)
|
||||||
|
|
||||||
|
The deferred ADR-0053 extension: a tier-3 **`hint.concept.*`** layer shown by
|
||||||
|
**F1** when the cursor sits **inside a recognized clause**, layered under the
|
||||||
|
per-form `hint.cmd.*` block. Seven topics — referential actions, `1:n`/`m:n`
|
||||||
|
cardinality, primary key, unique, check, foreign key.
|
||||||
|
|
||||||
|
- **Mechanism:** a new transparent `Node::Concept { topic, inner }` grammar
|
||||||
|
wrapper records the clause's byte span into `WalkContext::concept_spans`
|
||||||
|
(**append-only — survives the clause being fully matched**, unlike
|
||||||
|
`pending_hint_mode` which clears on match and so only knows the slot
|
||||||
|
boundary). `concept_topic_at_cursor` walks the full buffer and returns the
|
||||||
|
**innermost** containing span. No use of the dormant `WalkBound::Position`.
|
||||||
|
- **Two user forks:** detection = "anywhere inside the clause"; **all four
|
||||||
|
clause families** in v1. **Mode-keyed examples** (`example.simple` /
|
||||||
|
`example.advanced`) honour ADR-0053 D6 for topics reachable in both modes;
|
||||||
|
`emit_tier3_block` picks by live mode.
|
||||||
|
- **`/runda` caught two design gaps before any code** (clause map missed the
|
||||||
|
simple-mode constraint suffix; single-`example` model collided with D6) —
|
||||||
|
both fixed. **Comprehensiveness gate**: a recursive `Node::Concept` visitor
|
||||||
|
cross-checks grammar wrappers ↔ `CONCEPT_TOPICS` ↔ catalogue blocks.
|
||||||
|
- 21 new tests (14 resolver, 3 gates, 3 F1 integration, 1 snapshot).
|
||||||
|
|
||||||
|
## §3. The working method (ADR-0059, merged #41; fixes #43, #44)
|
||||||
|
|
||||||
|
The session's main artifact — the trackable flow for the public repo:
|
||||||
|
|
||||||
|
- **PRs onto a protected `main`** (always-green; one direct-push carve-out,
|
||||||
|
§4), one logical change per branch, conventional prefixes, the `/runda`/DA
|
||||||
|
review pasted into each PR. **Merge commits (`--no-ff`)**; never
|
||||||
|
rebase/squash (append-only).
|
||||||
|
- **One worktree per branch** (`<repo>-worktree-<segment>`) — never switch the
|
||||||
|
primary checkout. `scripts/wt-new.sh <branch>` (off `origin/main`,
|
||||||
|
`--no-track`) / `scripts/wt-rm.sh <branch>` (removes only the **named**
|
||||||
|
worktree).
|
||||||
|
- **Reserve-first ADR numbering** — `scripts/adr-reserve.sh <slug>`. The fix
|
||||||
|
for the real collision problem: a contiguous integer needs an allocator and
|
||||||
|
plain git branches have none, so **`main` is the registry and an atomic
|
||||||
|
`git push` is the lock** (compare-and-swap, retried on contention),
|
||||||
|
recorded in the append-only ledger **`docs/adr/RESERVATIONS.log`**. The
|
||||||
|
number is **stable from creation** (safe in immutable commit messages +
|
||||||
|
cross-refs). Supersedes ADR-0000's placeholder-until-merge default;
|
||||||
|
subproject namespaces (`ADR-website/ci-NNN`) unchanged.
|
||||||
|
- **Branch protection** (you applied in Gitea): require PR + the `ci / gate*`
|
||||||
|
check + up-to-date-before-merge; **owner whitelisted for direct push** (the
|
||||||
|
reservation ledger line, now also handoff/session docs — §4).
|
||||||
|
- **Fixes found by dogfooding:**
|
||||||
|
- **#43** — `wt-clean` (auto-sweep of all merged worktrees) → explicit
|
||||||
|
**`wt-rm <branch>`**. The auto-sweep would have deleted long-lived
|
||||||
|
branches (`website`, `ci`) since they're merged into `main` too. Also
|
||||||
|
**`wt-new --no-track`**: branching off `origin/main` had set the new
|
||||||
|
branch's upstream to `origin/main`, so a bare `git push` errored on a
|
||||||
|
name-mismatch and suggested the dangerous `HEAD:main`.
|
||||||
|
- **#44** — CI **dedupe**: `push: branches: [main]` (was `['**']`) so a
|
||||||
|
push to a PR'd branch no longer runs the gate twice. On **Gitea** the
|
||||||
|
`push` and `pull_request` runs were byte-identical — Gitea has **no
|
||||||
|
merge-preview ref**; its `pull_request` checks out `refs/pull/N/head`, the
|
||||||
|
same commit a branch push would (`docs.gitea.com/usage/actions/faq`).
|
||||||
|
Keeping the gate on `pull_request` is forward-compatible: if Gitea ever
|
||||||
|
adds the merge ref, the runs upgrade to testing the merged result for free.
|
||||||
|
|
||||||
|
## §4. Decisions
|
||||||
|
|
||||||
|
- **#38 closed — won't build** the pre-submit-diagnostic tier-3 route. The
|
||||||
|
ADR-0053 D6 deferral reasons still hold: `Diagnostic` carries no class key
|
||||||
|
(a class field would have to thread through every diagnostic-creation
|
||||||
|
site — broad change) for marginal value (tier-2 already surfaces
|
||||||
|
diagnostics live; many classes duplicate the runtime-error/clause-concept
|
||||||
|
tiers). Reconsider only if a diagnostic class has genuinely unique teaching
|
||||||
|
value. Rationale recorded on the issue.
|
||||||
|
- **#40 deferred** (open): wire `CHANGELOG` into komac's winget
|
||||||
|
`--release-notes-url`. Best coupled to the **next `v*` release + first real
|
||||||
|
winget *update* test** — the initial winget PR to `microsoft/winget-pkgs`
|
||||||
|
is still unconfirmed after several days, so end-to-end validation needs a
|
||||||
|
confirmed package first.
|
||||||
|
- **Docs direct-push carve-out** (this handoff is the first to use it):
|
||||||
|
handoff / session docs (and the reservation ledger) are **owner
|
||||||
|
direct-pushed to `main`**, not PR'd. See §5 for *why* a PR doesn't work.
|
||||||
|
|
||||||
|
## §5. Process lessons (now in ADR-0059 / CLAUDE.md)
|
||||||
|
|
||||||
|
- **Update a branch in ONE lane** — locally (`git fetch && git merge
|
||||||
|
origin/main`), **not** the Gitea "Update branch" button when a conflict is
|
||||||
|
possible. The button silently mis-resolved the README clash on #42
|
||||||
|
(dropped the `0059` index row) and, combined with a local merge, diverged
|
||||||
|
the PR branch; healed with an append-only merge (no force-push).
|
||||||
|
- **Primary checkout rests on `main`; feature work in worktrees.** Mid-session
|
||||||
|
the primary was stuck on `feat` (bootstrap artifact), which is what made
|
||||||
|
worktree cleanup awkward — there was no `main` checkout holding the
|
||||||
|
scripts. Resolved by switching the primary to `main` and moving `feat` to a
|
||||||
|
worktree.
|
||||||
|
- **Docs-only PRs are blocked by the required gate.** `paths-ignore`
|
||||||
|
(`docs/**`, `**/*.md`) means a docs-only change posts **no `ci / gate`
|
||||||
|
run**, and branch protection requires `ci / gate*` — so the required check
|
||||||
|
never arrives and the PR is stuck "expected/waiting." That is the concrete
|
||||||
|
reason handoff/session docs are direct-pushed (§4). If docs-via-PR is ever
|
||||||
|
wanted, add a "skipped → success" gate shim (or drop the paths-ignore).
|
||||||
|
- **Gitea CI specifics worth remembering:** no merge-preview ref (above); the
|
||||||
|
reserve script's CAS via atomic push; `--no-track` on branch creation to
|
||||||
|
avoid the inherited-`origin/main` upstream.
|
||||||
|
|
||||||
|
## §6. Next
|
||||||
|
|
||||||
|
- **Next session is free to pick a feature** — no specific item is queued;
|
||||||
|
consult `docs/requirements.md` for the remaining backlog (e.g. **TT4 /
|
||||||
|
Tier-4-in-CI** still not wired; **D3 packaging** — winget pending
|
||||||
|
confirmation; the larger deferred UX items: tutorial system, session-log +
|
||||||
|
markdown export V4, multi-line input I1, ER-diagram export V3).
|
||||||
|
- **#40** when the next release happens (with the first winget update test).
|
||||||
|
- **Use the new flow:** `wt-new` to start a branch, `adr-reserve` the moment
|
||||||
|
an ADR is needed, PR onto `main`, `wt-rm` when done. Push/merge stay your
|
||||||
|
steps; agents prepare but never push.
|
||||||
|
|
||||||
|
## §7. Process pins
|
||||||
|
|
||||||
|
- Commits user-confirmed, no AI attribution, append-only. **Push/merge are
|
||||||
|
the user's steps.** This handoff + the §4 carve-out doc amendments are
|
||||||
|
direct-pushed to `main` by the owner (docs-only, paths-ignored,
|
||||||
|
owner-whitelisted).
|
||||||
Reference in New Issue
Block a user