Skip to content

NOW.md is a single-file merge bottleneck: every open PR is CONFLICTING, and merge=union makes it worse #2297

Description

@gHashTag

Problem

Every PR must update docs/NOW.md, and entries are prepended — so every PR
rewrites the same first line. All 18 currently-open PRs are marked
CONFLICTING by GitHub. The conflict is structural, not incidental: one file,
one anchor, ~35 PRs/day.

docs/NOW.md merge=union was added to make those merges automatic. Measured
against master @ 7e8de87b1, it does not do the job:

The damage is measurable on master today:

measurement value
^# NOW headings in docs/NOW.md 137
Last updated: lines 136
orphaned entry Wave Loop 421 close-out / Wave Loop 422 setup (2026-07-06)
headings with union's blank-line-eaten signature 5, all dated 2026-08-19/20

So the rule buys nothing where conflicts are reported, and costs real
conflict-detection where they are not.

Two further defects found in the same sweep

  1. tri hooks now-gate is dead code. cli/tri/src/hooks.rs matches
    ^\*\*Last updated:\*\* — a bold label. cli/tri/src/nownote.rs has
    only ever written the plain Last updated: form. Master contains 0
    bold occurrences against 136 plain. The gate can never pass on a real
    checkout.
  2. .gitattributes describes a file that does not exist. Its comment says
    "The root file is a symlink." git ls-tree shows 100644 blob for root
    NOW.md — a divergent regular file stamped Last updated: 2026-08-09.

Proposed fix

One file per entry: docs/now/<YYYY-MM-DD>-<slug>.md. Two PRs write two
different paths, so there is no shared line and nothing for GitHub to call
dirty. This is already the repo's dominant convention — docs/reports/ holds
1,564 date-stamped files, .claude/plans/ 417, and .trinity/experience/ is
one append-only file per track.

The gate keeps asserting both halves, unweakened:

  • presence — the diff must add (--diff-filter=A) a matching entry;
  • freshness — that entry's filename date must fall in
    [yesterday .. tomorrow] UTC, the same window as today;
  • content (new) — at least one heading and one bullet, because an empty new
    file would otherwise be the same vacuous pass a whitespace touch used to be.

merge=union is retired for both NOW.md and docs/NOW.md.

Explicitly out of scope

  • The 137 existing entries are not migrated. docs/NOW.md is frozen as a
    historical archive with a pointer header. Splitting it is mechanical and would
    make the change unreviewable.
  • The orphaned entry is not repaired. Its date cannot be recovered without
    guessing.
  • The 18 open PRs are not touched. Each needs one rebase to move its entry
    to docs/now/; there is no migration that spares them.
  • .trinity/experience.md, .trinity/current-issue.md and
    bootstrap/stage0/FROZEN_HASH have the identical pathology
    and are left
    alone. FROZEN_HASH is a one-line file every PR rewrites.

Note for the owner

This changes the contract of a required status check repo-wide. The PR will
be left open rather than auto-merged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions