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.

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