QEP-6: Project Tracker Structure and Order (Draft) - #18
QEP-6: Project Tracker Structure and Order (Draft)#18quantecon-services wants to merge 11 commits into
Conversation
Adds QEP-6 as a Draft: the project-tracking unit (one tracker issue, Project issue type, native sub-issues one level down), positional order with plan semantics, dependencies for real constraints, descriptive phase milestones, the fixed status stamp, and the body's no-mirror discipline with a single Next: resume line. Adds the README index row (standard / Draft / –). Discussion: #15 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013WNYd4EW71564zVcW81yx7
Folds in the twelve amendments consolidated on the field report thread (see #19) plus two edits from its producer-tooling finding: - Scope the standard to GitHub.com (s7) - Ban purely numeric milestone names, verified live (s4) - Membership criterion: closing a work item advances the definition of done; unparented issues and unparented trackers are normal (s1) - Direct children homogeneous in kind; progress is a snapshot, not a time series (s1) - Dropped items leave the sub-issue list - percent_completed counts not_planned closures as completed (s2) - Gates: mostly phase-level in practice; a whole-project gate also carries the tracker-to-tracker dependency edge (verified live on a throwaway pair); stated once, in the project that waits (s3) - Parked-ness is derived from open blockers, never carried (s3) - Stamp refresh is a read-modify-write with a lossless read; sanitising surfaces get append-only treatment (s5) - Named replacements for the body bans; Related work section (s6) - Markdown template plus post-creation type read-back (Adoption 1) - Re-parenting guard on the conform tooling (Adoption 2) - QEP-6 authoritative over the dashboard contract during handover (Adoption 3) - Drop "untyped = untriaged" as a load-bearing justification (s1) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Applied the field-test amendment set from #19 (the consolidated 12-amendment checklist in its final comment), plus the two edits from its producer-tooling finding, in commit 1a0f063. The four review calls landed as: Gates (amendment 10 §1) — the softened, granularity-first form: most cross-project gates are phase-level and stay in the body; a whole-project gate carries the tracker-to-tracker dependency edge, stated once in the body of the project that waits. The edge mechanism is now verified live rather than inferred (see the closing results on #20): an edge between two sub-issue-carrying tracker issues is accepted, reads back on REST Stamp concurrency (amendment 7) — the read half is specified as read-from-a-source-returning-surface (the REST endpoint returns raw markdown) rather than an unactionable byte-for-byte round-trip check; where only a sanitising surface is available the body is append-only and corrections go to comments. "untyped = untriaged" — dropped from §1 as a load-bearing justification for type-over-label; the Motivation's audit observation stands as an observation. Related work — bound relaxed to: entries name projects, never work items, but item numbers may appear as the specifics of a project-level relationship. Also in: amendment 2 upgraded from source-derived to executed ( Per process: Draft and unmerged, so no |
…s on labels Types carry structural role (Project / Task / Decision, each with its own meaning of "closed"); QEP-2 labels carry content, and the axes compose. Adoption gains the one-time reversible reshape of the org type set (Bug/Feature disabled, Task re-described, Decision created). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
e61b1da adds §2 Issue types, settling the type/label question from the tracker discussion: native issue types carry structural role (what kind of object an issue is in the tracking system), QEP-2 labels carry content at triage, and the axes compose — a work item whose content is a bug is The set is three roles, each admitted by having its own meaning of "closed": Adoption gains a one-time org-level precondition: reshape the type set via four reversible API calls — |
… not a tier Records the outcome of the #24 discussion in one scope sentence: the grammar has two normative tiers and no third; a programme is a named collection of projects maintained by the projects registry. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Finding 9 follow-up — the class-3 producer now conforms (2026-09-02)Closing the loop on qeps#19's finding 9, which read The six findings it filed (QuantEcon/skills#69–#74) are done: merged as QuantEcon/skills#76, released as Two things this draft's Adoption section did that mattered in practice. Clause 3's precedence sentence is what the skill cites where C2 and this QEP disagree — the skill names the disagreement (a body roster is C2-conformant, QEP-6-forbidden) and points at the clause rather than resolving it, which is exactly the one-sentence fix finding 9 asked for. And clause 2's read-before-link obligation was verified in the One re-verification note for the record: QuantEcon.py#925's stamp heading, which finding 9 called The link-and-reprioritise path was exercised once by hand the same day, placing the six closed findings into QuantEcon/skills#63 in plan order after an existing item; REST, GraphQL and the rendered page agreed on the result. The same body was brought to §7 by hand — roster table out, phase table and The evaluation gate finding 9 named still stands: until QuantEcon/status-projects#19 ships, the dashboard re-sorts children by issue number, so the ordering half of this draft is observable only on GitHub itself. Generated by Claude Code |
Field report — two trackers written to the draft, 2026-09-07 and 2026-09-08Two project trackers were written to QEP-6 as drafted by the org's own producers on consecutive days: QuantEcon/status-projects#69 (eleven items, three phases, one item closed) and QuantEcon/status-projects#89 (nine items, three phases), with a declared dependency between them. Both carry the 1. When the phase gate is a 2. An item-level constraint across projects was read as body material. #89 states three constraints on items in #69 (its collector item waits on #69's registry and collector items; its Overview item waits on #69's Focus item) with the sentence "That ordering is an edge between items in two different projects, so it is stated here rather than implied." §4 says the reverse — item constraints are native and may cross project boundaries — but its gate paragraph discusses "cross-project gates" at phase and project level only, which is where the reading came from. Proposed sentence after "an edge may cross project boundaries": An item-level constraint is a native edge on the two items whether or not they share a project; only phase-level and whole-project gates are stated in the body. A second, smaller miss: §7 gives the waited-on project a home for pointing back (gated by), and #69 has no such line — the gate was written by the waiting project alone, which is the case §4 describes and the case in which the other project is least likely to notice. 3. 4. The phase table is an undated claim outside the stamp, and it went stale within a day. #69's list moved from nine items to eleven on 2026-09-07 with a revision comment, adding a new surface and a new contract; the body's phase intents and Build exit criterion, verified that morning, still describe the nine. §6 dates the stamp section and §7 places the phase table outside it. Adoption clause 3 could oblige the 5. The ordering evidence window has a smaller sample than the clause implies. Adoption clause 4 is done — the collector publishes list order since 2026-09-07 (QuantEcon/status-projects#19) — but 19 of the 41 registered trackers are in private repositories and publish children as counts only, so list order is observable on the 14 public trackers that have sub-issues (the collection of 2026-09-08 03:55 UTC). Both trackers in this report are private and contribute nothing to the ordering half of the evidence. The late-September comment window should state its sample. Nothing here changes the draft's shape. The two amendments are one sentence each in §4; the third is a clarification across §1 and §2; the last two are observations for the evaluation. Postscript, the same day. The review was ruled on within the hour and both trackers were brought to the §2 and §4 form: #70 and #90 now block every Build item natively, #72 and #92 the site items, the three cross-project item constraints are edges, and one item carries an edge to the decision outside both projects — twenty-one edges, one |
Second field report — a degree census over four trackers, and one amendment to FR-2A review of all four dashboard projects (QuantEcon/status-projects#1, #69, #89, #23 — the 2026-09-08 report read two of them) read 1. The graph does not close, and no written count of it has been correctΣ The counts written on 2026-09-08 were 21 (this PR's postscript), 21 ( Nothing in the draft is wrong about this. It is offered as the strongest available evidence for Adoption clause 4's direction of travel: any consumer that publishes an edge count should compute it, and any producer that writes one by hand will be wrong within the day. 2. FR-2's back-pointer half should be struck rather than strengthened§4 puts the gate in the waiting project's body once and asks the other project to point back via a §7 GitHub already holds the inverse. Verified live: #73 reports And there is no producer to write it. The complete mutating-call table of An obligation with zero producers and a free platform inverse is one that will be missed every time. Proposed: drop the back-pointer duty from §4, and say instead that the reverse direction is read, never written. §7's 3. §4's phase-gate clause should name the conjunctionThe clause that sends phase-level gates to the body is what produced six uncarried orderings on these trackers (#73→#74, #74→#75/#76, #94→#95/#96/#97, #82→#84, #91→#92, #71→#72 — asserted in item bodies, carried by nothing). The platform already supports the honest carrier, and the alternatives were checked rather than assumed:
Proposed sentence for §4: A phase-level gate is carried as a conjunction — the first item of the waiting phase is blocked by every item of the phase it waits on — so the gate clears when the phase closes rather than when the tracker closes; the body states only why. Appendix A must change in the same commit. Its A related finding on §1, offered as an observation§1's homogeneity rule is falsified as a partition claim by this repository's own flagship project. #70 fans out to {#73, #74, #75, #76, #77} and #72 to {#75, #76, #67} — the two overlap on #75 and #76. So "a phase is the fan-out of its gate" cannot be assumed, and §5's accepted limit that "phases must partition the work" holds only for milestones — which can never be a dependency endpoint. Anything built on fan-out-as-phase is already untrue here. Four editorial items, all free while the window is unopened
Also, and separate from the text: this PR has no decision deadline, which QEP-1 step 3 requires in the PR description. That is deliberate here (the window awaits the collector's first month), but it is one of four open QEP PRs with no live deadline — filed as #26. Full evidence, including the census method and the seven corrections it produced, is in Generated by Claude Code |
…tream amendments Folds three ruled changes into this amendment and drops one it originally proposed, so v3 lands as one coherent round instead of a v3 that a v4 would immediately partly delete. Ruled 2026-09-08; discussion on #26, #9 and #22. DROPPED FROM THIS AMENDMENT: the one-week default comment window. The ruling went further than shortening it. THE DECISION DEADLINE GOES. Step 3 of "How a QEP is decided" is struck and the acceptance trigger becomes "no objection is outstanding" rather than a date — lazy consensus with no clock, so a QEP nobody objects to still lands without needing the lead, and nothing is accepted by the mere passage of time. Roles, the Summary's "clear deadline" promise, and the README's Proposing steps all follow. The evidence is recorded under Alternatives considered: on 2026-09-08 none of the four open QEP pull requests had a live deadline — #8 had never set one in 47 days, #13's and #23's had passed, #18's was deliberately deferred — while nothing in CI ever read a PR description. The field was required by this document and checked by nothing. Enforcing it in CI was considered and declined: it would have turned three open PRs red for a rule they predated. THE README INDEX IS GENERATED, post-merge from frontmatter and ordered by number, so a PR carries no row of its own and two QEP PRs cannot collide on one line of one table. The mechanism shipped ahead of this amendment in #30, together with the ordered-list check; Automation now names both, and a stale index is a warning rather than a failure. Numbering states what already happened informally: a number is reserved when its draft PR opens, released if that PR closes unmerged, so index gaps are normal while drafts are open. A DOWNSTREAM QEP CARRIES ITS UPSTREAM AMENDMENTS — #9's sentence, widened by the case it did not anticipate. Where the superseded standard is not itself a QEP, the Adoption section must name the contract, the obligation and a date by which the handover completes: QEP-6 asserts precedence over an external tracker contract with no date on it, and the qe skills depend on that sentence at runtime. Closes #9. Also brings the branch up to date with main, which had moved on by QEP-3's merge (this branch predated it, so it carried neither the file nor its index row). Verified green under both the pre-#30 checks on this branch and #30's new ones, including the ordered-list rule over the rewritten Adoption entry. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hwm5shrGXmaq4r3Lp9kS33
…tion 1-5 The Draft repairs ruled on 2026-09-08, from the two field reports on this PR and a review of all four dashboard projects. The comment window has not opened and there are no reviews on this PR, so every edit here is a free Draft edit: no version, no window reset. SECTION 4, THE PHASE GATE. The clause that sent phase-level gates to the body "because no object represents a phase" is what produced six uncarried orderings across two conformant trackers. The dependency graph is many-to-many, which is enough: the first item of the waiting phase is blocked by every item of the phase it waits on. Linear in the upstream phase rather than a cross-product, it publishes how many upstream items are still open, and it clears when the PHASE closes rather than when the upstream tracker closes. The alternatives were checked against the live graph rather than reasoned about. A tracker-to-tracker edge over-parks: section 4 says it asserts nothing in the blocked project may start, and status-projects#89's Decide phase is being worked now. A single tail edge under-carries: of #69's five Build items, #76 and #77 both report blocking 0 and the five have no chain between them, so closing the tail implies nothing about the rest. SECTION 4, THE ITEM EDGE. Made explicit that an item-level constraint is a native edge whether or not the two items share a project (FR-2's first half) — a producer read the gate paragraph's "cross-project" as covering item edges and wrote three of them as prose. SECTION 4, THE DECISION GATE. Where a phase's exit criterion is a single Decision closing, the gate is a decision gate: the object exists, so each item that waits carries the edge to it (FR-1). Both producers read section 2 and section 4 as pointing different ways here and both chose the body. SECTION 4, THE BACK-POINTER IS STRUCK. Blocked-by and blocking are two ends of one edge — verified live, #73 reports blocking 1 while #94 reports blocked_by 3 — so the waited-on project needs no back-pointer to stay in step. No qe skill writes a dependency edge at all, so the obligation had zero producers and a free platform inverse: it will be missed every time, and was. A Related work line stays available prose in section 7, not an obligation. SECTION 1. Decision children are compatible with either homogeneous kind, a closed-completed Decision counts toward progress like any child, and a consumer may render decisions apart (FR-3). Two of eleven and two of nine children on the reviewed trackers are decisions, and the Themes programme tracker carries seven beside four project trackers. SECTION 8. "No producer or consumer reads programme membership as structure" stops being true the day the dashboard's programme read ships, so it now separates the producer duty from a consumer's observation: observing a front door creates no duty on any tracker and no third tier. APPENDIX A. Its Gates line restated both struck rules verbatim, and it is the text producers copy — so it changes in the same commit, as the field report asked. ADOPTION IS RENUMBERED 1-5. The source read 1., 2., 2., 3., 4.; Markdown renumbers on render, so the published document showed 1-5 while every external "clause N" citation after the first was off by one. Clause 4 also gains FR-4's obligation: re-stamp the section in the same turn as any change to the list, because the phase table is an undated claim outside the one section whose contract is that its claims are re-verified on update, and it went stale within a day of a re-plan. FRONTMATTER gains related: [2] with the matching header-table row, which check.mjs has always enforced as a pair and which this QEP — the one that reasons most explicitly about another — did not carry. THE README INDEX ROW IS REMOVED rather than merged. This branch predated QEP-3's merge and both inserted a row after QEP-2's, which is what made the PR unmergeable. Under the generated-index rule the row is derived from frontmatter, so stripping it returns README to its base content and the merge with main is clean. Note the consequence: until #30 lands, this branch's own check.mjs still requires a row per QEP file, so CI here is red until then. That ordering is deliberate. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hwm5shrGXmaq4r3Lp9kS33
Draft repairs pushed —
|
| Alternative | Why it fails |
|---|---|
| Tracker-to-tracker edge | §4 itself: it asserts nothing in the blocked project may start. status-projects#89's Decide phase is being worked now, so it would be false |
| Single tail edge | Of #69's five Build items, #76 and #77 both report blocking: 0 and the five have no chain between them — closing the tail implies nothing about the rest |
| A new gate object | Fails on cost, and on §1: a gate is not a work item, so it distorts the progress denominator |
§4 — three more changes
- The item edge is explicit. An item-level constraint is a native edge whether or not the two items share a project (FR-2's first half). A producer read the gate paragraph's "cross-project" as covering item edges and wrote three of them as prose.
- The decision gate. Where a phase's exit criterion is a single
Decisionclosing, the gate is a decision gate — the object exists, so each waiting item carries the edge to it (FR-1). Both producers read §2 and §4 as pointing different ways and both chose the body. - The back-pointer obligation is struck. Blocked-by and blocking are two ends of one edge — verified live, #73 reports
blocking: 1while #94 reportsblocked_by: 3— so the waited-on project needs nothing to stay in step. And noqeskill writes a dependency edge at all, so the obligation had zero producers and a free platform inverse. §7'sgated byline stays available prose rather than an obligation the standard leans on.
§1, §8 and Appendix A
- §1 —
Decisionchildren are compatible with either homogeneous kind; a closed-completedDecisioncounts toward progress like any child; a consumer may render decisions apart (FR-3). - §8 — "No producer or consumer reads programme membership as structure" stops being true the day the dashboard's programme read ships, so it now separates the producer duty from a consumer's observation: observing a front door creates no duty on any tracker and no third tier.
- Appendix A — its
Gates:line restated both struck rules verbatim, and it is the text producers copy, so it changes in the same commit as the field report asked.
Editorial
- Adoption is renumbered 1–5. The source read
1., 2., 2., 3., 4.; Markdown renumbers on render, so the page showed 1–5 while every external "clause N" citation after the first was off by one. Clause 4 also gains FR-4's obligation: re-stamp the section in the same turn as any change to the list. related: [2]and the matching header-table row.check.mjshas always enforced these as a pair, and this QEP — the one that reasons most explicitly about another — carried neither.
The README conflict is gone, and how
mergeable_state was dirty on one line: this branch predated QEP-3's merge and both inserted a row after QEP-2's. The row is removed rather than merged. Under the generated-index rule (#30) it is derived from frontmatter, so stripping it returns README to its base content and the merge with main is clean — which it now is; main is merged in and QEP-3 arrives with it.
One deliberate consequence: until #30 lands, this branch's own check.mjs still requires a row per QEP file, so CI here is red with README index has no row for QEP-6. That is the expected ordering, not a defect — #30 first.
Verified
| Check | Result |
|---|---|
This branch's pre-#30 check.mjs |
fails on the missing index row — expected, see above |
#30's check.mjs |
passes, with the stale-index warning |
| #30's ordered-list rule | passes — it previously reported line 364 against line 349, which is the Adoption defect this commit fixes |
check-labels.mjs |
passes |
FR-5 is deliberately not in the document: the ordering-evidence sample belongs in the comment window's own statement, not in the standard. It is recorded in my earlier field report above.
Generated by Claude Code
…; Adoption 4 names its discharging item Three repairs from the adversarial review of the 2026-09-08 rulings. §4 states the test that decides whether an ordering is an edge at all: output, not order. An edge is written where the downstream item cannot start without something the upstream produces; two items that touch the same file or will be worked in sequence are plan order, and stay with the body's sequencing rationale. The same test decides what a gate is — a phase-level gate is a real constraint by definition, a phase-level preference is not a gate. The case study that prompted it: #89's "Build waits on #69's Build" was coordination written as a gate, and the conjunction was about to carry it. Appendix A's Gates line follows. §8 no longer says a consumer "may observe" a programme's front door — that is QuantEcon/status-projects#10's open question and this QEP has no business answering it. The scope keeps what is its own: no programme tier in the grammar, no duty on a tracker from being listed. Adoption clause 4 names the item that discharges the tracker-contract handover, QuantEcon/status-projects#114, in place of an open-ended "until that contract's planned handover" — the form QEP-1 v3 requires for a precedence clause over an external standard. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Hwm5shrGXmaq4r3Lp9kS33
QEPs are the source of truth and are independent of every repository: a downstream consumer adapts to a QEP, and the QEP owes it nothing back. The dashboard's tracker contract is a consumer that must conform, not a peer standard this QEP supersedes — so Adoption item 4 no longer asserts precedence over it, no longer prescribes its handover, and no longer names a tracking issue in another repository. How each consumer reaches conformance, and when, is that consumer's own business. Also drops the citation of QEP-1's cross-standard amendment rule, which was withdrawn from the v3 amendment in #23; the reasoning is recorded on #9. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adoption item 4: the precedence clause over the dashboard's tracker contract is removedPushed in b9f31a1, following the ruling of 2026-09-09 on #23 (reasoning recorded on #9): a QEP is the source of truth and is independent of every repository. A downstream consumer adapts to a QEP; the QEP owes it nothing back. Under that model The citation of QEP-1's cross-standard amendment rule goes with it — that rule was withdrawn from the v3 amendment in #23, so it will not exist to cite. It was the only reference to QEP-1 in this document. Ownership is now recorded from the other side, in the repo that holds the contract: QuantEcon/status-projects#140. QuantEcon/status-projects#114 stays open there as that repo's own work. Unrelated and pre-existing: |
…QEP's Item 5 prescribed an edit to another repository's contract and code — "a one-row contract change plus a sort removal, verified once against a deliberate re-order on a public tracker" — which is the same overreach removed from item 4 on 2026-09-09, in a quieter register. Nothing normative is lost. Section 3 already states the rule for every consumer: order is an operational property, not a published field; a consumer that publishes a child list preserves list order, and none may require, parse, or infer sequence from names. Item 4's closing sentence generalises the rest — how each consumer reaches conformance, and when, is that consumer's own business. The item was also stale. QuantEcon/status-projects ruled the same change itself on 2026-09-07 in their issue 19: the contract row now reads "list order, exactly as subIssues returns it", and the collector's sort is gone rather than rewritten. The consuming repo got there on its own reasoning, without the QEP obliging it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Adoption item 5 is removedPushed in 16bd810. Item 5 prescribed an edit to another repository's contract and its code — "a one-row contract change plus a sort removal, verified once against a deliberate re-order on a public tracker." That is the same overreach removed from item 4, in a quieter register: the QEP specifying a consumer's implementation and its verification method. Nothing normative is lost. §3 already states the rule for every consumer — order is an operational property, not a published field; a consumer that publishes a child list preserves list order, and none may require, parse, or infer sequence from names. Item 4's closing sentence carries the rest: how each consumer reaches conformance, and on what schedule, is that consumer's own business. Adoption is now 1–4. The item was also staleQuantEcon/status-projects made the change itself on 2026-09-07, ruled in their issue 19, a day before this branch was last pushed. Their contract row now reads "list order, exactly as That behaviour is unguarded by any test, which is a real gap but theirs, not this QEP's — QuantEcon/status-projects#142 now tracks it there. Where the cross-repo material went
|
…al case Section 3's consumer clause covered one behaviour — preserve list order when publishing a child list. It now states the principle it was a case of: a consumer that republishes a tracker presents the structure the tracker expresses, membership as recorded and in the position the tracker places it, rather than an arrangement of its own. The reason is stated with it, and it is the general one: a consumer that re-sorts or re-groups makes a conformant tracker and a non-conformant one publish identically, so the standard cannot be evaluated from what is published. That covers re-grouping as well as re-sorting, and applies to any consumer rather than to the one this QEP happened to know about. Names no repository and describes no repository's current behaviour, which is what Adoption item 5 did before it was removed. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Follow-up: §3's consumer clause now states the principlePushed in 59fa374. Removing Adoption item 5 left the consumer rule stated only as a special case — "a consumer that publishes a child list should preserve list order." That is one behaviour, not the principle behind it, and it left the QEP without a general statement of what a consumer owes a tracker. §3's closing paragraph now reads:
Three things this gets right that the old pairing did not. It covers re-grouping as well as re-sorting. It applies to any consumer rather than the one this QEP happened to know about. And it carries the reason with the rule — the evaluability argument, which is the strongest case for the rule and was previously only implicit. It names no repository and describes no repository's current behaviour. That was the defect in item 5: a QEP that records what an external repo does today is stale the moment that repo changes, and item 5 was already stale when it was removed. |
Records the cross-QEP amendment convention in `AGENTS.md` as author-side practice, rather than folding it into QEP-1 as #23 originally proposed. Ruled 2026-09-09; the reasoning is on #9, which this retires. ## Why here and not in QEP-1 QEP-1 already says amend in place and bump `version` — "put the edit in the PR that needs it" is the mechanical consequence, not a separate rule. It is author-side judgement of exactly the kind QEP-1's *Automation* section already delegates to `AGENTS.md`, alongside substantive-vs-editorial and the commit subject. And `AGENTS.md` is the document an author actually reads before drafting a QEP, which is where the convention needs to be to change anything. The second-instance rule that #9 was waiting on never fired, either: QEP-2 ↔ QEP-4 is intra-repo and QEP-6 ↔ status-projects is cross-repo — two problems with one instance each, not two instances of one problem. ## Three paragraphs The first is the original convention from #9: don't forward-reference a draft from an accepted QEP, and put the upstream edits in the downstream QEP's own branch so reference and target land in one commit. Unchanged in substance — it is how QEP-2 ↔ QEP-4 already works, with the removed hook wording preserved in the `qep-0004` branch's *Amendments to QEP-2* section. The second records the ruling that the convention stops at this repo's boundary. A QEP is the source of truth and is independent of every repository: it states the rule, and a consuming repo owns how and when it conforms. Precedence clauses, handover obligations and tracking-issue references for another repository do not belong in a QEP — an issue number in a repo this one does not own is a status pointer that rots, and a QEP states rules rather than tracking their adoption elsewhere. The third extends that from pointers to **descriptions**, added after QEP-6 supplied the worked example. Its Adoption item 5 said the projects dashboard re-sorts children by issue number and prescribed the remedy — a one-row contract change, a sort removal, and the test to verify it. status-projects had already removed the sort on its own reasoning two days earlier, and for a better-stated reason than the QEP gave. So the QEP shipped a stale claim *and* an obligation discharged before it was written, and nothing would have signalled either. What survives instead is the principle with its reason attached: §3 now says a consumer that republishes a tracker presents the structure the tracker expresses, because a consumer that re-sorts or re-groups makes a conformant tracker and a non-conformant one publish identically. That holds whatever any consumer does next. ## Already applied - #23 dropped the QEP-1 amendment; v3 is now three changes. - #18 dropped QEP-6's precedence clause and cross-repo handover item, removed Adoption item 5 entirely, and generalised §3's consumer clause to a principle. - Ownership is recorded from the other side in QuantEcon/status-projects#140, and the one thing genuinely missing there — a regression guard for list-order publishing — is QuantEcon/status-projects#142. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…cend (#30) Two mechanical changes and the `AGENTS.md` text that follows from them. Ruled 2026-09-08; discussion on #26, items 2 and 4. **No QEP text changes**, so no version question — QEP-1's own *Automation* section wants a matching edit and that lands with the v4 amendment carrying #26's other items. ## 1. The README index is generated `stamp.mjs` previously synced the `Type` and `Version` columns of rows that already existed. It now **rebuilds the whole table from each QEP's frontmatter, ordered by number** (`renderIndex`/`buildRow` in `qeps.mjs`, which read column positions from the table header so a reordered or extended table needs no code change). `check.mjs` no longer requires a PR to carry its own row and no longer enforces `Type`/`Status`/`Version` parity — a stale table is a **warning, not a failure**. **Why.** The table is a merge-conflict magnet: four open QEP PRs contend for rows in one table, and #18 is currently unmergeable on that single line against QEP-3's row. **What this does and does not fix.** A branch that *already* carries a row will still conflict textually — strip the row. But a **mis-resolved index conflict is now self-healing**, because the post-merge regeneration restores the table from frontmatter whatever the resolution did to it. So a QEP that merges out of numeric order slots into position automatically, and gaps while drafts are open need no later hand-insertion. That last point is the answer to "what if QEP-6 merges before QEP-5". ## 2. Ordered-list markers must ascend in source Markdown **renumbers an ordered list on render**, so a source list reading `1., 2., 2., 3., 4.` displays as 1–5 while every external *"clause N"* citation silently shifts by one. QEP-6's Adoption section is exactly that, and it survived a twelve-amendment review (#19), a field report and four PR comments. Fenced blocks are exempt; blank lines do not end a run; a more-indented line is treated as an item's continuation and a deeper list as independent. ## 3. `AGENTS.md` follows, in four places - The index section now says the table is generated and must not be hand-edited, with the gap and conflict behaviour spelled out. - *Drafting* and *Accepting* stop telling authors to write a row — status lives in **two** places in the document, not three. - A new section: **cite a section by its heading, not its number.** Inserting §2 into QEP-6 mid-draft renumbered §2–§7 to §3–§8 and forced a correction onto a ruling that had already cited them; the `qe` skills, the dashboard's tracker contract and several tracking issues all cite these. - *Accepting* also records that a merged QEP may not carry `status: Draft` — QEP-3 did, for two months (#27, being fixed in #29). ## Verification Each claim was tested rather than reasoned about: | Test | Result | |---|---| | Generator against the current index | reproduces it **byte-for-byte** — a no-op on correct input | | `check.mjs` with QEP-6's file present and no row for it | passes, with the warning — the relaxation works | | Monotonic check against the real `qep-0006-project-trackers.md` | reports line 364 against line 349 — catches the live defect | | `stamp.mjs` on a correct tree | *nothing to stamp or sync* | | `stamp.mjs` after deleting QEP-3's row **and** flipping QEP-2's `Status` to `Draft` | both repaired; tree returns to the committed content exactly | `node .github/scripts/check.mjs` → *QEP checks passed.* `node .github/scripts/check-labels.mjs` → *Label appendix checks passed (1 companion file(s)).* ## Suggested landing order Before #18's QEP-6 repairs — it makes that PR's one-line `dirty` conflict disappear rather than needing a both-rows resolution. The `check.mjs` condition refusing `status: Draft` on `main` is deliberately **not** here: it must land after #29, or it fails on QEP-3 itself. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01Hwm5shrGXmaq4r3Lp9kS33 --- _Generated by [Claude Code](https://claude.ai/code/session_01Hwm5shrGXmaq4r3Lp9kS33)_ --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Matt McKay <mmcky@users.noreply.github.com>
…task-ordering-9uj7wa
|
Field note, 2026-09-10 12:16 AEST — the first live application of §4's output, not order test. On 2026-09-08 a phase-level gate was ruled between two of the dashboard projects in QuantEcon/status-projects (private): one project's Build phase would open when the other's closed, on the ground that the two touch the same files and one agent works them serially. Read against §4 as drafted at this PR's head, that ground is coordination rather than a constraint, and the owner ruled today that the gate is withdrawn to sequencing rationale. The needs between the two projects that survive the test are carried as item-level native edges, each a site item drawing a document a collector item produces; three were written today. Recorded on QuantEcon/status-projects#127, with the question as it stood before the ruling. Two observations for the draft. The test did real work: it reversed a ruling made the same day under the pre-amendment text, which is the case for the sentence staying. And the reversal turned on the two phrases the original ruling used to justify itself, shared files and serially, which are the two examples §4 already names as non-constraints, so a producer reading §4 first would not have written the gate. |
Adds QEP-6: Project Tracker Structure and Order as a Draft — the one-page unit spec scoped by the 2026-08-23 ruling on the discussion issue, extended with the ordering question that arrived from the field (QuantEcon/textstrata#8, QuantEcon/skills#55) and answered on that thread.
What it decides
Projectissue type (a type, not a label — QEP-2 untouched; resolves QEP-2 field report: no type label fits plan/tracking issues #11); work items are native sub-issues, progress on direct children only, never body checkboxes (unmeasured ≠ 0%).Phase gates stay in the body.Superseded — see the repairs below.## Where we stand (verified YYYY-MM-DD)canonical; banner fallback). The stamp section sits at the top and may open with a singleNext:resume line — the body's only "what's next" claim; the list is the authority if they disagree.qeskills, which cite this QEP.Repairs since opening — 2026-09-08
The bullets above describe the Draft as opened; four things have moved in this PR's later commits (
bc856da,3673475), all ruled on the discussion threads and the two field reports on this PR:Decision; a whole-project gate as a tracker-to-tracker edge. It also states the test that decides whether an ordering is an edge at all — output, not order: an edge where the downstream item cannot start without something the upstream produces; shared files and serial work are plan order and stay with the body's sequencing rationale — and a phase-level preference is therefore not a gate. The back-pointer duty on the waited-on project is struck: the reverse direction is read, never written. Appendix A'sGates:line follows.1., 2., 2., 3., 4., so every external "clause N" citation after the first was off by one; ci: generate the README index, and check that ordered-list markers ascend #30 now checks for this. Clause 4 obliges a re-stamp in the same turn as any change to the list, and states that theqeskills conform to this QEP — the precedence clause over the dashboard's tracker contract, and the cross-repo handover item, were removed on 2026-09-09 (see the comment thread; ownership is recorded in QuantEcon/status-projects#140).related: [2]and a Related header row are added. The README index row is removed: ci: generate the README index, and check that ordered-list markers ascend #30 generates the index post-merge, so this PR'schecksjob is red until ci: generate the README index, and check that ordered-list markers ascend #30 lands, and is expected to be. Landing order: ci: generate the README index, and check that ordered-list markers ascend #30 → QEP-3: Accepted #29 → QEP-1 v3: stamp from v0; drop the decision deadline; generate the index #23 → this.Points where input is most useful
Next:resume line — right affordance, right home?Process
Opened as a draft, consistent with the 2026-08-23 ruling that the spec is field-tested in Draft: the conform tooling (QuantEcon/skills#63, which carries the split of #49) brings registered trackers into the layout and the collector reports compliance nightly. Under QEP-1 v3 (#23) there is no comment window or decision deadline to set: the Draft is accepted when a Core Maintainer other than its author approves it with no objection outstanding. Note the ordering half cannot be observed until the child-order amendment ships — the collector currently re-sorts children, which is itself part of the motivation.
qep-checksparity: new QEP, unversioned (implicitly v0); no README row (generated by #30). Both check scripts pass locally under #30's rules.🤖 Generated with Claude Code
https://claude.ai/code/session_013WNYd4EW71564zVcW81yx7
Generated by Claude Code