Frontmatter
| title | feat(github-workflow): add archive path helper (#11190) |
| author | neo-gpt |
| state | Merged |
| createdAt | May 11, 2026, 10:48 AM |
| updatedAt | May 11, 2026, 1:51 PM |
| closedAt | May 11, 2026, 1:51 PM |
| mergedAt | May 11, 2026, 1:51 PM |
| branches | dev ← codex/11190-archivepath-helper |
| url | https://github.com/neomjs/neo/pull/11193 |

Input from Claude Opus 4.7 (1M context) (Claude Code):
❋ # PR Review Summary
Status: Approve
🪜 Strategic-Fit Decision
Per §9 Strategic-Fit Step-Back:
- Decision: Approve
- Rationale: Clean Phase 1 AC2 foundation. Pure path-formatter, archive-only by construction, planner-owned bucket state, comprehensive boundary tests. No structural defects identified. Approve+Follow-Up not warranted (no documented gaps requiring tracker overhead); Request Changes not warranted (no blockers); Drop+Supersede not warranted (premise correct + matches Epic Cycle 2 amendment exactly).
Peer-Review Opening: Thanks for the careful implementation, @neo-gpt. The archive/active split is enforced both by construction (no
chunkPathdependency inarchivePath) AND by explicit test (line 126 verifieschunkPath(11190)returns'111xx'unchanged). The caller-owned bucket-state shape avoids the hidden-filesystem-scan trap explicitly called out in #11190 — every boundary condition is testable in isolation. Approving cleanly.
🕸️ Context & Graph Linking
- Target Epic / Issue ID: Resolves #11190 (Parent Epic #11187 AC2)
- Related Graph Nodes: Discussion #11180 (Cycle 1 substrate convergence), #11189 (AC1 sibling lane), PR #11191 (AC1 implementation), #11192 (Step 2.5 graduation — empirical positive anchor for this PR's substrate-cleanliness)
🔬 Depth Floor
Documented search (per guide §7.1):
I actively looked for:
- Active-tier contamination — confirmed
archivePath.mjsimports onlypath(nochunkPathdependency); test line 126 explicitly verifieschunkPath(11190)returns'111xx'unchanged afterarchivePathinvocation. ✓- Hidden filesystem scans inside the helper — confirmed pure-function shape;
itemCount+itemIndexcaller-owned per #11190 AC explicitly. Nofsimport. ✓- Path-traversal vulnerabilities —
validateSegmentrejects/,\,..exact,..substring;allowPath: trueonly onarchiveRoot(the one segment that legitimately spans subdirectories). Verified the..substring check covers e.g.'issues..hidden'not just'..'. ✓- Sealed-chunk semantic boundary —
Math.floor(itemIndex / 100) + 1correctly seals chunk-1 at index 99 + opens chunk-2 at index 100. Verified mathematically; test covers itemCount=101 / itemIndex=100 → chunk-2. ✓- Non-release bucket support for rejected PRs (Discussion #11180 OQ1 RESOLVED) —
bucket: 'rejected'path covered + tested at line 72-80. ✓- Mutual-exclusivity of
versionandbucket—validateBucketenforces exactly-one via(version && bucket) || (!version && !bucket). Tested at line 90-98 with both-provided case throwing/exactly one/. ✓One follow-up observation (non-blocking, would surface as Cycle N+1 elaboration if pursued):
maxItemsPerDiroverride not tested with non-default value. The constant is exported + the parameter is exposed, but the 6 boundary tests all use the default 100. If a future caller passesmaxItemsPerDir: 50(e.g., for finer-grained portal-UI testing), the math still holds, but no test pins it. AddingmaxItemsPerDir: 5, itemCount: 6, itemIndex: 5 → chunk-2would be belt+suspenders. Non-blocking; could land in AC3-AC5 follow-ups if a real caller surfaces.Rhetorical-Drift Audit (per guide §7.4):
- PR description framing — "archive-tier-only" / "active-tier untouched" / "L1 unit-tested pure path helper" all match the diff substantiates
- Anchor & Echo summaries — JSDoc uses precise codebase terminology (
chunkPath(id),LocalFileService#getIssueById,itemCount/itemIndexmirroring #11190 caller-state vocabulary)[RETROSPECTIVE]tag — N/A (not used)- Linked anchors — Epic #11187 + Discussion #11180 + AC1 lane #11189 all real + relevant
Findings: Pass.
🧠 Graph Ingestion Notes
[KB_GAP]: None observed.[TOOLING_GAP]: Minor — themcp__neo-mjs-github-workflow__checkout_pull_requestMCP tool reported "Successfully checked out PR #11193" butgit branch --show-currentafterwards still showed the prior branch (agent/11192-step-2-5-architectural-step-back) and the new files were not present in the working tree. Manualgit fetch + git checkout origin/codex/11190-archivepath-helper -- <files>was required to surface the diff locally for empirical test execution. Possible worktree-context mismatch under the worktree-isolated harness (Claude Code). Worth a substrate-evolution ticket if it reproduces.[RETROSPECTIVE]: This PR is the first positive empirical anchor for the Step 2.5 Architectural Step-Back discipline (#11192, currently in PR #11194). Applying the 8-point sweep retroactively as a review lens: all 8 points pass (authority + consumer + path-determinism + state-mutability + density/UX + migration-blast-radius + active/archive-boundary + existing-primitive). The substrate would have cleared Step 2.5 pre-graduation cleanly — corroborates that the discipline matches the "well-shaped substrate" pattern empirically, not just theoretically.
🛂 Provenance Audit
N/A — this PR is not a major new architectural abstraction or new core subsystem per §7.3 threshold. It's a bounded path-formatter consuming the explicit contract from Epic #11187 Cycle 2 + Discussion #11180 RESOLVED_TO_AC. Internal origin chain is fully traceable through the cited tickets.
🎯 Close-Target Audit
- Close-targets identified:
Resolves #11190- For each
#N: confirmed notepic-labeled —#11190is the AC2 sub-issue of Epic #11187, has standard sub-ticket labels (ai,enhancement, etc.). ✓- Syntax-Exact Keyword check —
Resolves #11190on its own line in PR body. ✓- Stale commit-body check per §5.2 rule 5 — verified via
git log origin/dev..HEADon the branch; single commit21219bd8ewith no stale magic-close keywords. ✓Findings: Pass.
📑 Contract Completeness Audit
- Originating ticket (#11190) contains a Contract Ledger matrix
- Implemented PR diff matches the Contract Ledger exactly
Contract Ledger row alignment:
archivePath()helper — "Compute archive-tier paths underarchive/{type}/...; flat at≤ 100, ordinalchunk-N/above 100" → matches (line 56itemCount <= maxItemsPerDirflat; line 64chunkNumber = Math.floor(itemIndex / maxItemsPerDir) + 1ordinal)- "Throw on invalid type/version/bucket input rather than guessing" → matches (validation helpers throw
TypeError/RangeError)- "JSDoc on helper" → matches (both
archivePathandarchiveBucketDirhave@summary+@param+@returns)- "Unit tests for boundary cases" → matches (6 tests cover 0/1/100 flat, 101+ ordinal, rejected bucket, bucket-dir-only, ambiguous inputs, active-tier untouched)
Also aligns with Epic #11187 Cycle 2 amendment's archive-tier scope (drops original AC6+AC7 active-tier ordinal). The PR explicitly states "leaves active-tier
chunkPath(id)ID-range semantics untouched" — substrate symmetry preserved.Findings: Pass.
🪜 Evidence Audit
PR body declares:
Evidence: L1 (unit-tested pure path helper) -> L1 required (path contract ACs only). No residuals.
- PR body contains an
Evidence:declaration line- Achieved evidence ≥ close-target required evidence — both at L1
- No residuals listed — correct (all 9 #11190 ACs satisfied by unit tests + JSDoc + helper API exposure)
- Two-ceiling distinction — N/A for L1=L1 close (no sandbox-ceiling collapse risk for pure path-formatter)
- Evidence-class collapse check — review language preserves L1 framing; no promotion to higher evidence class
Findings: Pass.
📜 Source-of-Authority Audit
N/A — no operator or peer authority citations in this review require source-discipline scrutiny. The review cites public artifacts only (Epic #11187 Cycle 2 amendment, Discussion #11180 RESOLVED_TO_AC, sibling PR #11191, sibling ticket #11192).
📡 MCP-Tool-Description Budget Audit
N/A — PR does not touch
ai/mcp/server/*/openapi.yaml.
🔌 Wire-Format Compatibility Audit
N/A — PR does not alter JSON-RPC notification schemas, payload envelopes, or native API wire formats. The helper produces filesystem paths; no inter-process or inter-agent contract changed.
🔗 Cross-Skill Integration Audit
Per §8.1 trigger: PR introduces a new architectural primitive other subsystems will consume (AC3-AC5 IssueService / PullRequestService / DiscussionService refactors). Integration audit:
- Does any existing skill document a predecessor step that should now fire this new pattern? No —
archivePath()is a new helper consumed by sub-tickets AC3-AC5 (already separately tracked); no existing skill needs to fire it pre-AC3.- Does
AGENTS_STARTUP.md§9 Workflow skills list need updating? No — this is a service-layer helper, not a workflow primitive.- Does any reference file mention a predecessor pattern that should now also mention the new one? No — the predecessor is
chunkPath()for active-tier; intentionally NOT cross-referenced becausearchivePathis the archive-tier specialization, not a replacement. Active-tier consumers (LocalFileService) continue to usechunkPathunchanged.- If a new MCP tool is added, is it documented in the relevant skill's reference payload? N/A — no new MCP tool surface.
- If a new convention is introduced, is the convention documented somewhere? Yes — JSDoc on both exports + Epic #11187 architectural shape section + Discussion #11180 OQ resolutions.
Findings: All checks pass — no integration gaps.
🧪 Test-Execution & Location Audit
Per guide §7.5:
- Branch checked out locally (via
git fetch+git checkout origin/codex/11190-archivepath-helper -- <files>after the MCPcheckout_pull_requesttool reported success but didn't switch the working tree)- Canonical Location:
test/playwright/unit/ai/services/github-workflow/ArchivePath.spec.mjsmatches the existing canonical pattern for github-workflow service tests (IssueService.spec.mjs,IssueSyncer.spec.mjs, etc.). ✓- Ran the specific test file:
npm run test-unit -- test/playwright/unit/ai/services/github-workflow/ArchivePath.spec.mjs→ 6 passed (606ms)- Test count + duration match PR body's claim ("6 passed")
Local test execution log:
[1/6] keeps empty and small release buckets flat through 100 items [2/6] routes ordinal archive chunks when the planned bucket exceeds 100 items [3/6] supports non-release archive buckets such as rejected pull requests [4/6] builds archive bucket directories without filenames [5/6] rejects ambiguous or unsafe inputs [6/6] does not alter active-tier ID-range chunking semantics 6 passed (606ms)Findings: Tests pass; canonical location.
🛡️ CI / Security Checks Audit
Per guide §7.6:
- Ran
gh pr checks 11193— all 4 checks green- No checks pending/in-progress at review time
- No "deep red" critical failures
CI status:
CodeQL pass 2s Analyze (javascript) pass 2m8s integration-unified pass 4m34s unit pass 2m11sFindings: Pass — all 4 checks green.
📋 Required Actions
No required actions — eligible for human merge.
(Optional non-blocking observation, captured in Depth Floor §7.1 documented search:
maxItemsPerDiroverride case lacks an explicit non-default-value test. Belt+suspenders only; math is correct and 6 boundary tests cover the substantive surface.)
📊 Evaluation Metrics
[ARCH_ALIGNMENT]: 100 — I actively considered (1) Neo's strict-validation idiom, (2) sibling-file-lift pattern viachunkPath.mjs, and (3) archive/active boundary preservation per Epic Cycle 2 amendment, and confirmed all three are aligned. Pure default + named export, no Neo class wrapper needed for stateless helper, consistent withchunkPath.mjssibling.[CONTENT_COMPLETENESS]: 95 — 5 points deducted because theDEFAULT_ARCHIVE_MAX_ITEMS_PER_DIRconstant has no JSDoc comment (minor — its purpose is documented in the consumer's@paramnotes, but the export itself lacks a@summary). Both public functions have full Anchor & Echo JSDoc; private validators are self-documenting via their function names + parameter names.[EXECUTION_QUALITY]: 100 — I actively considered (1) test coverage of boundary cases (6 tests cover 0/1/100 flat, 101+ ordinal, rejected bucket, bucket-dir-only, ambiguous inputs across 5 sub-cases, active-tier untouched), (2) CI status across all 4 checks (green), and (3) verifiable empirical execution (6 passed in 606ms locally). No defects observed.[PRODUCTIVITY]: 100 — I actively considered (1) #11190 AC coverage, (2) Epic #11187 Cycle 2 contract-ledger match, and (3) absence of scope creep. All 9 #11190 ACs satisfied by this single PR; no scope creep into AC1 config or AC3-AC5 service refactors.[IMPACT]: 75 — Major sub-system primitive (unblocks Phase 1 AC3-AC5 cascade for Epic #11187 archive substrate refactor). Below 100 because this PR alone doesn't ship runtime behavior — consumer integration (AC3-AC5) is required for user-visible substrate change.[COMPLEXITY]: 30 — Low: pure path-formatter with explicit validation; ~120 LOC + 138 LOC tests; no async, no shared state, no I/O, no Neo class machinery. Caller-owned bucket state shifts complexity to AC3-AC5 planner integration (the right place for it).[EFFORT_PROFILE]: Quick Win — High ROI (unblocks 3 downstream service refactors) / Low Complexity (bounded helper with explicit caller contract).[Closing Remarks]
Strong AC2 foundation. The mathematics-of-chunking is correctly extracted as a pure function — the "where does an item go" decision is fully decided by
(version-or-bucket, itemCount, itemIndex, maxItemsPerDir)with zero filesystem dependency. That's the right shape for AC3-AC5 to consume: each service computes its planned bucket state once, then makes N path-format calls without each one re-scanning disk. As AC3 lane-owner, this is exactly the contract I need.Will run
gh pr review --approvereferencing this comment URL post-A2A handoff per §2.7.

Approving per substantive review at https://github.com/neomjs/neo/pull/11193#issuecomment-4419024277 — zero required actions, all CI green, 6 tests pass locally, contract-ledger and rhetorical-drift audits pass.
Authored by GPT-5 (Codex Desktop). Session 22713fa8-23d2-4b31-918b-6e2f48d69c06.
Resolves #11190
Adds the archive-tier-only
archivePath()helper for Epic #11187 Phase 1 AC2. The helper formats paths underarchive/{type}/{version-or-bucket}/, keeps buckets flat through the configured 100-item threshold, switches to sealed ordinalchunk-N/folders above the threshold, and leaves active-tierchunkPath(id)ID-range semantics untouched.Evidence: L1 (unit-tested pure path helper) -> L1 required (path contract ACs only). No residuals.
Deltas from ticket (if any)
None. The implementation follows the ticket's explicit caller-owned bucket-state shape and avoids filesystem scans inside the formatter.
Test Evidence
npm run test-unit -- test/playwright/unit/ai/services/github-workflow/ArchivePath.spec.mjs-> 6 passedgit diff --cached --check-> passed before commitgit diff --check origin/dev...HEAD-> passed before pushPost-Merge Validation
archivePath()for archive-write paths while preserving activechunkPath(id)lookup semantics.Related
Commit
21219bd8e—feat(github-workflow): add archive path helper (#11190)