Repository navigation
docs(requirements): repoint REQ-0002's three paths — stale the day they were written (#1933) - #1942
Merged
Merged
Conversation
…the day they were written `docs/requirements/0002-it-services-project-delivery-and-cost.md` cited three `src/` paths that no longer exist. #1924 / PR #1932 froze them as a requirements record. The ancestry says otherwise: the commit that authored the record (9f13c77) is a descendant of the ADR-0130 layout move (36b27dd), and all three paths are already absent from `src/` in that very commit's own tree. They never named anything — a typo, not a true-when-written record, and freezing protects statements that were true when written. `docs/requirements/README.md` calls a record "the spec an agent starts from", read "before writing any `*.object.ts`", and PSA is this thread's next step, so an agent building it from this record is routed into directories that do not exist. - `src/objects/` → `src/sales/objects/`. The four objects the sales half is judged against — `crm_account`, `crm_contact`, `crm_lead`, `crm_opportunity` — are the sales package's. - `src/flows/opportunity-approval.flow.ts` → `src/sales/flows/opportunity-approval.flow.ts`. - `src/flows/billing-handoff.flow.ts` → both successors. The move split that flow in two by trigger and there is no same-named successor, so a prefix would still have named nothing. The record cites it as evidence for the 2026-08-02 ruling that HotCRM models no orders, invoices or payments, and each half carries that ruling in its own header, so the record names each half: `src/sales/flows/billing-handoff-closed-won.flow.ts` (an opportunity enters `closed_won`) and `src/revenue/flows/billing-handoff-contract-activated.flow.ts` (a contract enters `activated`). REQ-0003 … REQ-0006 already spell the package-qualified form, so this brings REQ-0002 into line with its own siblings. Nothing else in the record changes. `docs/architecture/module-split-plan.md` and `module-split-inventory.json` are untouched: those describe the pre-move tree on purpose, which is a different case, and the policy question they raise is the maintainer's. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01T3YsvpK1PvYf9n1YUhYP6W
|
The latest updates on your projects. Learn more about Vercel for GitHub. |
os-elon-musk
marked this pull request as ready for review
September 15, 2026 19:13
This was referenced Sep 15, 2026
os-elon-musk
pushed a commit
that referenced
this pull request
Sep 16, 2026
…written The maintainer ruled the freeze question on 2026-09-16, verbatim and untranslated: > 写时为真的陈述冻结;写下时就已失效的路径按错误改正。这条写进 `docs/requirements/README`,以后不再逐卡吵。 `docs/requirements/README.md` gains one section that writes it down as a criterion rather than a conclusion, so the next reader can decide a record nobody has argued about yet. The criterion is two timestamps: the commit that wrote the sentence, against the commit that moved, renamed or deleted the structure it cites. Earlier means the sentence was true when written and is frozen; later means it named nothing the day it was typed, which is a typo to correct. The measurement is given in the cheap, shallow-safe form — a lookup in the authoring commit's own tree rather than an ancestry walk — with the shallow-checkout trap that makes `--diff-filter=A` read like a real answer called out beside it. The "why" hangs on this file's own opening, which already defines these records as "the human-or-customer input an AI agent reads before authoring metadata": a path that resolved to nothing the day it was written has no fact underneath it, so freezing it protects nothing and routes the next agent into a directory that does not exist. Both worked examples are already in this directory and come out opposite ways, which is what makes the criterion testable rather than decorative: REQ-0001 is frozen (its commits predate the ADR-0130 move, and the directory it names is in the tree at its own commit), REQ-0002 was corrected in PR #1942 (its commit lands 29 minutes after that move, and none of the three paths it cited are in the tree at that commit). No requirement record changes, the template is untouched, and the section states that it does not decide the document class that describes a superseded tree on purpose. Claude-Session: https://claude.ai/code/session_01T3YsvpK1PvYf9n1YUhYP6W Co-authored-by: Claude <noreply@anthropic.com>
os-elon-musk
pushed a commit
that referenced
this pull request
Sep 16, 2026
…written
The maintainer ruled the freeze question on 2026-09-16. The wording below is that
ruling as adopted rather than as typed — the PM put it to the maintainer, who adopted
it with 「其他同意」 ("agreed to the rest") — so it is quoted exactly and kept
untranslated, because the adopted words are the ruling.
> 写时为真的陈述冻结;写下时就已失效的路径按错误改正。这条写进 `docs/requirements/README`,以后不再逐卡吵。
`docs/requirements/README.md` gains one section that writes it down as a criterion
rather than a conclusion, so the next reader can decide a record nobody has argued
about yet. The criterion is two timestamps: the commit that wrote the sentence,
against the commit that moved, renamed or deleted the structure it cites. Earlier
means the sentence was true when written and is frozen; later means it named nothing
the day it was typed, which is a typo to correct.
The measurement is given in the cheap, shallow-safe form — a lookup in the authoring
commit's own tree rather than an ancestry walk — with the shallow-checkout trap that
makes `--diff-filter=A` read like a real answer called out beside it.
The "why" hangs on this file's own opening, which already defines these records as
"the human-or-customer input an AI agent reads before authoring metadata": a path
that resolved to nothing the day it was written has no fact underneath it, so
freezing it protects nothing and routes the next agent into a directory that does
not exist.
Both worked examples are already in this directory and come out opposite ways, which
is what makes the criterion testable rather than decorative: REQ-0001 is frozen (its
commits predate the ADR-0130 move, and the directory it names is in the tree at its
own commit), REQ-0002 was corrected in PR #1942 (its commit lands 29 minutes after
that move, and none of the three paths it cited are in the tree at that commit).
No requirement record changes, the template is untouched, and the section states that
it does not decide the document class that describes a superseded tree on purpose.
Claude-Session: https://claude.ai/code/session_01T3YsvpK1PvYf9n1YUhYP6W
Co-authored-by: Claude <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #1933 — the implementation half only, per the PM's 2026-09-15 comment on that card.
decision+fixcardand its policy half stays with the maintainer; the merge queue would otherwise take the card
out of the open-issue inbox that half is waiting in. What is still open on #1933 after this lands:
the ruling on what a requirements record frozen at triage owes when it is also an agent's
authoring input — and, standing on that ruling,
docs/architecture/module-split-plan.md,module-split-inventory.json, and the half of theTREE_DOCSroster that #1923 left hand-writtenfor exactly this reason.
What this corrects
#1924 / PR #1932 judged 246 dead-path sites one at a time and kept these three, on the ground
that a requirements record is frozen at triage. PM review reversed that single site — the only one
of the 246 where PM and the implementing seat disagreed. The reversal rests on a measurement:
freezing protects a statement that was true when written, and these three never were.
Ancestry reading
The checkout is shallow, so a negative ancestry answer would need a control leg. The reading
below needs none: both legs are positive (exit 0 self-proves in any checkout), and the
load-bearing one is a tree lookup at a single commit, which traverses no ancestry at all.
36b27dd—refactor(layout): a directory under src/ is a package …(refactor(layout): a directory under src/ is a package — move every authored file into sales / service / revenue / marketing #1910), 2026-09-14T14:07:19Z9f13c77—docs(architecture): PSA module design, REQ-0002 …(docs(architecture): PSA module design, REQ-0002, and the final ADR-0130 module shape #1906), 2026-09-14T14:36:11Z⇒ 29 minutes after the layout move, the record was written citing three paths the move had
already removed, while all four correct paths were already sitting in the same tree. Stale the day
they were written — a typo, not a record.
REQ-0001 stays frozen, and this measurement is why. Two positive legs, no negative needed:
⚠️ Note for anyone re-running this:
git merge-base --is-ancestor 3b72afa 36b27ddanswers 0 (the shallow graft root precedes themove) and
git cat-file -e 3b72afa:docs/requirements/0001-agency-tier-lead-tagging.mdanswers 0(REQ-0001 was already there). Its
src/flows/*at line 20 was true when written and is untouchedhere.
git log --diff-filter=Anames3b72afaas REQ-0001'sadding commit, which is a shallow-boundary artifact, not a fact — the real add is beyond the
graft. The two legs above avoid depending on it.
The three repoints
9f13c77?src/objects/src/sales/objects/src/flows/opportunity-approval.flow.tssrc/sales/flows/opportunity-approval.flow.tssrc/flows/billing-handoff.flow.tsThe prefix is per-file, not uniform: the sales half's four objects (
crm_account,crm_contact,crm_lead,crm_opportunity) and the amount-approval flow are the sales package's, while thecontract-activated hand-off is the revenue package's.
REQ-0003 … REQ-0006 already spell the package-qualified form, so this only brings REQ-0002 into
line with its own siblings.
Why the hand-off citation names two files
src/flows/billing-handoff.flow.tshas no same-named successor — the ADR-0130 move split itby trigger, so mechanically adding a prefix would have produced a second path naming nothing. The
record cites the file as evidence for the 2026-08-02 ruling that HotCRM models no orders, invoices
or payments, and each half carries that ruling in its own header:
So the citation names each half, with what fires it:
src/sales/flows/billing-handoff-closed-won.flow.ts(an opportunity entersclosed_won) andsrc/revenue/flows/billing-handoff-contract-activated.flow.ts(a contract entersactivated).Verification
pnpm verify—package.jsonis the single source of truth for that chain and it was run whole,not narrowed. Run on the final head of this branch, under the shared heavy-verify lock; the exit
code was captured by the lock wrapper, never read through a pipe.
sibling work. The verdict, not the duration, is the reading.
Plus a resolution check with both controls, on the working tree: every
src/path the record nownames resolves on disk (4/4), and the two paths it used to name still do not (the checker can
report a miss, so 4/4 is a measurement rather than a vacuous pass).
Changeset
.changeset/req-0002-repoint-the-three-stale-paths.md, empty frontmatter — the sanctioned"releases nothing" declaration
.github/workflows/changeset-check.ymldocuments, on par with theskip-changesetlabel. Rationale: the whole diff is underdocs/requirements/(internalmaintainer documentation) plus the changeset itself. Nothing under
src/orcontent/docs/moves,the package is
private: truewith nofiles[], and the built artifact and the publisheddocumentation site are byte-identical to
main. This matches the level chosen by the two nearestprecedents — PR #1932 and the commit that created this very record (#1906) both used empty
frontmatter for maintainer-docs-only diffs, while #1921 carried a
patchprecisely because itmoved
content/docs/, the published half.Acceptance notes
Observations found on the way, none acted on here:
docs/requirements/TEMPLATE.mdline 33 teaches the retired flat layout — the B bulletevery new requirement record is copied from says "the standard metadata to add/change under
src/{type}/", one level short of the post-ADR-0130src/{package}/{type}/. PR docs: keep the record, repoint the pointer — the ADR-0130 dead paths in docs/, scripts/ and the root configs #1932's 246-sitesweep never reached
docs/requirements/at all (its diff is 8 files, none of them here), sothis has not been judged by anyone. An author following it writes into a directory that does not
exist, and a file that never reaches a package barrel is registered by nothing while
pnpm validatestays at exit 0. Reported for triage rather than repaired here: this PR's filesurface is one file and three paths, and the template is not a record, so it is not covered by
the ruling [decision] what does a frozen requirements record owe when it is also an AI's input surface — the same ruling governs three document classes (REQ-0002 half already repaired in #1942) #1933 is waiting on either way.
docs/requirements/**for deadsrc/paths.TREE_DOCSintest/docs-src-tree-paths.test.tsdoes not list this file, which is why the three survived adedicated sweep. Successor named: the policy half of [decision] what does a frozen requirements record owe when it is also an AI's input surface — the same ruling governs three document classes (REQ-0002 half already repaired in #1942) #1933, which [finding] docs-src-tree-paths is green over a Mermaid diagram naming 13 removed directories (inlineSrcDirs needs a trailing slash), and its own failure message instructs the next agent to use five dead paths #1923 left that roster
hand-written for.
crm_opportunitybullet's second line is now 97 characters against the file's ~90 wrap.Left unwrapped on purpose so the diff is one line per repoint; no guard measures it.
docs/architecture/module-split-plan.mdandmodule-split-inventory.jsonare untouched, asdirected: both describe the pre-move tree on purpose.
Generated by Claude Code