Skip to content

[#187] fix: target-layout packaging rewrites relative link depth#193

Merged
rucka merged 5 commits intomainfrom
feature/#187-fix-target-layout-link-depth
Apr 11, 2026
Merged

[#187] fix: target-layout packaging rewrites relative link depth#193
rucka merged 5 commits intomainfrom
feature/#187-fix-target-layout-link-depth

Conversation

@rucka
Copy link
Copy Markdown
Collaborator

@rucka rucka commented Apr 11, 2026

PR Information

PR Title: [#187] fix: target-layout packaging rewrites relative link depth
Story/Epic: #187 / #67
Type: Bug Fix
Priority: P0
Assignee: @rucka
Labels: bug

Summary

What Changed

Added depth-aware relative link rewriting in copyFileToTemp when packaging from target layout. After writing a .md file to the temp directory, if layout === 'target', the fix computes the depth delta between the file's original target location and its destination source location, then calls rewriteLinksInFile from @pair/content-ops to adjust relative ../ links.

Why This Change

pair package --layout target reads files from target paths (e.g., .claude/skills/pair-xxx/ — 3 levels deep) but writes them to source paths (e.g., .skills/pair-xxx/ — 2 levels deep). Relative ../ links were copied verbatim, producing broken links in the packaged artifact. Consumers installing from the package got incorrect internal links.

Story Context

User Story: As a KB author packaging from target layout, I want pair package --layout target to rewrite relative links to match source-layout depth so that the packaged artifact validates cleanly with kb-validate --layout source.
Acceptance Criteria:

AC Description Status
AC-1 Target pkg rewrites links to source depth
AC-2 ALL relative links in ALL .md files adjusted
AC-3 Package passes kb-validate --layout source
AC-4 Source layout packaging unchanged (regression)
AC-5 External/anchor links untouched

Changes Made

Implementation Details

  • Depth-aware link rewriting: In copyFileToTemp, when layout === 'target' and file is .md, compute originalDir (target path relative to project root) and newDir (source path), call rewriteLinksInFile to adjust relative links
  • Reuse content-ops infrastructure: Uses existing rewriteLinksInFile from @pair/content-ops (same mechanism used by install/update commands)
  • No-op guard: When originalDir === newDir (same depth), skip rewriting entirely
  • Order preserved: Depth rewrite happens after content write, before --root absolute rewriting
  • Manual test case: Added MT-CP806 to CP8 for release validation of this fix
  • Adoption update: Documented qa/ location in way-of-working.md and CLAUDE.md

Files Changed

  • Modified: apps/pair-cli/src/commands/package/zip-creator.ts — added depth-aware link rewriting in copyFileToTemp
  • Modified: apps/pair-cli/src/commands/package/zip-creator.test.ts — 5 new test cases
  • Modified: qa/release-validation/CP8-packaging.md — added MT-CP806, renumbered MT-CP807
  • Modified: .pair/adoption/tech/way-of-working.md — documented qa/ as manual test location
  • Modified: CLAUDE.md — added qa/release-validation/ to Key References

Testing

Test Coverage

  • Unit Tests: 5 new tests in zip-creator.test.ts — bug reproduction, regression, edge cases
  • Integration Tests: Real FS round-trip test with ZIP extraction and checksum verification
  • Manual Testing: MT-CP806 added to CP8 for release validation

Test Results

Test Suite: ✅ 747 passing (65 files)
Quality Gate: ✅ All passing (ts:check, test, lint, prettier, mdlint)

Testing Strategy

  • Happy Path: Target-layout skill file with 3-level relative links → packaged with 2-level links
  • Edge Cases: External links (https://), anchor-only links (#), same-depth registries (no-op), mixed content (selective rewriting)
  • Error Handling: N/A (rewriter silently skips non-rewritable links)
  • Regression: Source-layout packaging unchanged; existing --root rewriting unaffected

Quality Assurance

Code Quality Checklist

  • Code follows established style guides and conventions
  • Error handling implemented for edge cases
  • No debugging code or console logs left behind

Review Areas

  • Business Logic: Depth delta computation (originalDir vs newDir) is correct for all registry configurations
  • Code Structure: Reuses existing rewriteLinksInFile from content-ops — no new abstractions
  • Performance: No measurable impact (link rewriting already done in install/update paths)

Deployment Information

Deployment Notes

  • Dependencies: No new dependencies (reuses existing @pair/content-ops export)
  • Breaking Changes: None — fix only affects --layout target packaging path

Rollback Plan

Revert commit; no data migration needed.

Dependencies & Related Work

Related PRs

  • Follows: #182 (target-layout validation fix — prerequisite, closed/done)

Follow-up Work

  • Monitoring: Verify fix in next release via MT-CP806 manual test

Closes #187

rucka added 5 commits April 11, 2026 19:55
- Reproduce bug: target-layout packaging doesn't adjust relative link depth
- .claude/skills/ (3 deep) → .skills/ (2 deep) links not rewritten
- Task: T-1

Refs: #187
- Rewrite relative links when packaging from target to source layout
- Compute depth delta using originalDir (target) vs newDir (source)
- Use content-ops rewriteLinksInFile for consistent link adjustment
- Depth rewrite applied before --root absolute rewriting
- Task: T-2

Refs: #187
- Source layout packaging does NOT rewrite links (AC-4)
- External links and anchors preserved in target-layout (AC-5)
- Same-depth source/target is a no-op
- Task: T-3

Refs: #187
- Package from target layout with depth-adjusted links
- Verify rewritten content in extracted ZIP
- Verify package passes checksum verification
- Task: T-4

Refs: #187
- MT-CP806: manual test for target-layout link depth rewriting
- Renumber old CP806→CP807
- way-of-working: document qa/ as manual test location
- CLAUDE.md: add qa/release-validation/ to Key References

Refs: #187
@rucka rucka marked this pull request as ready for review April 11, 2026 18:08
Copy link
Copy Markdown
Collaborator Author

@rucka rucka left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: #193 — [#187] fix: target-layout packaging rewrites relative link depth

Review Information

Reviewer: AI-assisted review
Review Date: 2026-04-11
Story: #187 / Epic #67
Review Type: Bug Fix
Decision: ✅ APPROVED

Review Summary

Clean, minimal bug fix that adds depth-aware relative link rewriting when packaging from target layout. Reuses existing rewriteLinksInFile from @pair/content-ops — no new abstractions or dependencies. All 5 acceptance criteria are covered by tests.

Code Review Checklist

Functionality

  • Requirements Met — all 5 AC validated by dedicated tests
  • Business Logic — depth delta computation (originalDir vs newDir) is correct
  • Edge Cases — external links, anchors, same-depth registries all tested
  • Performance — no measurable impact (rewriter already used in install/update paths)

Code Quality

  • Readability — clear inline comment explaining the depth rewriting block
  • Maintainability — reuses existing infrastructure, no new modules
  • NamingoriginalDir/newDir clearly convey intent

Technical Standards

  • Style Guide — quality gate passes (ts:check, test, lint, prettier, mdlint)
  • Architecture — no new dependencies, no ADR needed
  • Dependencies@pair/content-ops already in tech-stack

Security Review

No security concerns — no user input, no external calls, no secrets.

Testing Review

  • Unit Tests — 5 new tests: bug reproduction, source-layout regression, external/anchor preservation, same-depth no-op, mixed content
  • Integration Tests — real FS round-trip: package → extract → verify checksum + link depth
  • Manual Testing — MT-CP806 added to CP8 for release validation
  • Test Clarity — tests are well-named and commented with depth explanations

Documentation Review

  • way-of-working.md — documented qa/ as manual test location
  • CLAUDE.md — added qa/release-validation/ to Key References
  • CP8-packaging.md — MT-CP806 added, MT-CP807 renumbered

Positive Feedback

  • Exemplary bug-fix workflow: failing test first (T-1), then fix (T-2), then regression + integration (T-3, T-4)
  • Smart reuse of rewriteLinksInFile — avoided reimplementing link rewriting
  • Guard clause originalDir !== newDir prevents unnecessary work for same-depth registries
  • Round-trip integration test with real FS + checksum verification is thorough

Risk Assessment

Risk Impact Probability Mitigation
Regression in source-layout packaging Medium Very Low Dedicated regression test covers this
--root + --layout target interaction Low Low Root rewrites to absolute first; depth adjustment is no-op on absolute links

Tech Debt

No debt items flagged.


REVIEW COMPLETE:
├── PR:         #193: [#187] fix: target-layout packaging rewrites relative link depth
├── Story:      #187: Bug: target-layout link depth off-by-one
├── Decision:   APPROVED
├── Issues:     critical: 0 | major: 0 | minor: 0
├── Quality:    PASS — all gates
├── DoD:        met (pending merge + smoke tests)
├── Adoption:   no new deps, manual check confirms compliance
├── Debt:       0 items flagged
└── Report:     Posted as PR comment

@rucka rucka merged commit 33e90ba into main Apr 11, 2026
1 check passed
@rucka rucka deleted the feature/#187-fix-target-layout-link-depth branch April 11, 2026 18:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bug: pair package --layout target produces .skills/ output with links still relative to .claude/skills/ depth (off-by-one ../)

1 participant