What failed
Nightly run, test node:
tests/unit/test_plan_docs.py::test_plan_declares_a_tracking_issue[codex-skills-review-revisions.md]
Exact failure output:
tests/unit/test_plan_docs.py:46: in test_plan_declares_a_tracking_issue
assert _TRACKING_RE.search(head), (
E AssertionError: codex-skills-review-revisions.md has no resolvable `tracking:` frontmatter. Add a `tracking:` line naming the issue this plan owns (a `#N` token or an issue URL) within the first 12 lines, or add the file to NON_LANE_PLANS in tools/plan_doc_scope.py if it is not a lane plan.
E assert None
E + where None = <built-in method search of re.Pattern object at 0x10e0a0ee0>('---\nstatus: Ready\ntype: bug\nappetite: Small\ntracking: null\n---\n\n# Codex skills review revisions\n\n## Problem\n\nReview of commit 858b7ca4d found that native skill creation cannot satisfy the')
E + where <built-in method search of re.Pattern object at 0x10e0a0ee0> = re.compile('^tracking:.*(?:#\\d+|issues/\\d+)', re.MULTILINE).search
Likely cause
docs/plans/codex-skills-review-revisions.md carries tracking: null in its frontmatter. The regex in tests/unit/test_plan_docs.py requires a resolvable #N token or an issue URL, so null does not satisfy it.
The plan is deliberately issue-less. Its own Problem section says:
This task uses the user's request and review findings as its acceptance contract; no synthetic tracking issue or managed SDLC lane is needed.
So the author intentionally opted out of a tracking issue but never completed the second half of the escape hatch the assertion message names: adding the filename to NON_LANE_PLANS in tools/plan_doc_scope.py. That frozenset currently holds only session-recovery-observation-audit.md and resilience-simplification-three-tier.md.
Introducing commit (the plan doc has exactly one commit in its history):
89f800876 2026-09-14 Tom Counsell Add native Codex skills with scoped discovery and installation (#3213)
The plan landed on main without a tracking issue and without a NON_LANE_PLANS entry, which is what turned the nightly red.
Reproduces on origin/main
Yes. Reproduced at origin/main head b13dc8ad3078381bce5fb37fc3502def37c7e654, via scripts/pytest-clean.sh on the single node. This is not a worktree-local or ordering artifact; the plan file on main is the input.
Suggested next steps
Decide which of the two the plan actually is, then apply the matching fix:
- If it is genuinely not a lane plan (what its prose asserts), add
"codex-skills-review-revisions.md" to NON_LANE_PLANS in tools/plan_doc_scope.py with a comment explaining why, matching the style of the existing two entries.
- If it should own an issue, file that issue and replace
tracking: null with tracking: #N.
Worth a follow-up either way: a plan doc with tracking: null reached main, so whatever gate is supposed to catch this before merge did not fire. Checking why is probably more valuable than the one-line fix.
Triage 2026-09-15
Status: confirmed still failing on main 205344717.
Single-line hotfix: Yes. Add "codex-skills-review-revisions.md", to the NON_LANE_PLANS frozenset in tools/plan_doc_scope.py:20 (alongside the existing two entries, each with a comment explaining why it's excluded — this plan explicitly declares "no synthetic tracking issue or managed SDLC lane is needed").
Reduce-complexity option: The guard is pulling its weight and isn't a mechanical ratchet — it doesn't grow with repo size, it only fires when a plan lands without registering its tracking/exemption status. This is a one-off missed escape-hatch registration, not a systemic drift. Worth a separate, smaller follow-up (already flagged in the issue) on why the pre-merge gate didn't catch tracking: null before this reached main, but the guard itself should stay as-is.
What failed
Nightly run, test node:
Exact failure output:
Likely cause
docs/plans/codex-skills-review-revisions.mdcarriestracking: nullin its frontmatter. The regex intests/unit/test_plan_docs.pyrequires a resolvable#Ntoken or an issue URL, sonulldoes not satisfy it.The plan is deliberately issue-less. Its own Problem section says:
So the author intentionally opted out of a tracking issue but never completed the second half of the escape hatch the assertion message names: adding the filename to
NON_LANE_PLANSintools/plan_doc_scope.py. That frozenset currently holds onlysession-recovery-observation-audit.mdandresilience-simplification-three-tier.md.Introducing commit (the plan doc has exactly one commit in its history):
The plan landed on main without a tracking issue and without a
NON_LANE_PLANSentry, which is what turned the nightly red.Reproduces on origin/main
Yes. Reproduced at
origin/mainheadb13dc8ad3078381bce5fb37fc3502def37c7e654, viascripts/pytest-clean.shon the single node. This is not a worktree-local or ordering artifact; the plan file on main is the input.Suggested next steps
Decide which of the two the plan actually is, then apply the matching fix:
"codex-skills-review-revisions.md"toNON_LANE_PLANSintools/plan_doc_scope.pywith a comment explaining why, matching the style of the existing two entries.tracking: nullwithtracking: #N.Worth a follow-up either way: a plan doc with
tracking: nullreached main, so whatever gate is supposed to catch this before merge did not fire. Checking why is probably more valuable than the one-line fix.Triage 2026-09-15
Status: confirmed still failing on main
205344717.Single-line hotfix: Yes. Add
"codex-skills-review-revisions.md",to theNON_LANE_PLANSfrozenset intools/plan_doc_scope.py:20(alongside the existing two entries, each with a comment explaining why it's excluded — this plan explicitly declares "no synthetic tracking issue or managed SDLC lane is needed").Reduce-complexity option: The guard is pulling its weight and isn't a mechanical ratchet — it doesn't grow with repo size, it only fires when a plan lands without registering its tracking/exemption status. This is a one-off missed escape-hatch registration, not a systemic drift. Worth a separate, smaller follow-up (already flagged in the issue) on why the pre-merge gate didn't catch
tracking: nullbefore this reached main, but the guard itself should stay as-is.