[PR #587] [MERGED] fix(artifacts): break directory child collation ties #2088

Closed
opened 2026-10-16 21:14:05 +00:00 by bsakaguchi · 0 comments
Owner

📋 Pull Request Information

Original PR: https://github.com/morluto/rea/pull/587
Author: @kaoru0822-kitauji
Created: 10/5/2026
Status: ✅ Merged
Merged: 10/5/2026
Merged by: @morluto

Base: main ← Head: fix/artifact-directory-collation-ties


📝 Commits (1)

  • b013fec fix(artifacts): break directory child collation ties

📊 Changes

3 files changed (+158 additions, -3 deletions)

View changed files

➕ src/application/ArtifactGraphConstruction.test.ts (+47 -0)
📝 src/application/ArtifactGraphConstruction.ts (+12 -3)
📝 tests/boundary/filesystem/artifactDirectoryIdentity.test.ts (+99 -0)

📄 Description

Summary

Break collation ties when ordering virtual-directory children so equivalent member permutations retain the same directory fingerprint within the same collation environment.

No tracking issue: found during real ZIP inventory/comparison testing; no matching dedicated issue or PR was found. This addresses the explicitly deferred equal-collation case from #580.

Problem and expected behavior

Distinct valid names can compare equal under localeCompare. For example, a.txt and a name with U+200B inserted after a both pass path validation but collate equally.

The old stable sort retained their archive enumeration order. Reversing only those members changed the verified pkg directory ID and made compare_artifacts report a spurious directory content/relations change. This also reproduces when the files contain identical bytes, so an artifact-ID tie-breaker would not suffice.

Change and scope

Retain every nonzero result from the existing locale comparator. Only when names collate equally, compare their UTF-16 code units. A small application-internal comparator helper makes that ordering directly testable.

The hash shape, child-relative names, and normal non-tied ordering are unchanged. Corrected tie ordering may change affected virtual-directory IDs and propagate to ancestor directory IDs.

This is deliberately not a cross-locale/ICU identity guarantee or a claim of complete root/inventory/occurrence/edge determinism. No fixed locale or wholesale comparator replacement is introduced, and other sorting sites remain untouched.

Contract and boundary impact

  • Semantic owner and earliest changed stage: application graph construction, sorting child records before virtual-directory hashing.
  • CLI and MCP/tool-catalog contract: unchanged schemas/tools; corrected virtual-directory identities flow into existing inspection/comparison.
  • Provider, bridge, target-format, or platform compatibility: real ZIP fixtures executed on Linux; no reader or provider changes.
  • Evidence, artifact, provenance, or reconstruction contract: keep distinct observed names significant; preserve byte identities and unaffected directory fingerprints. Ancestor directory fingerprints can change when an affected child is corrected.
  • Process execution, authorization, cleanup, or containment impact: none; no extraction, new execution, or validation relaxation.
  • Generated metadata, package, or installation impact: none.

Evidence and regression coverage

  • Real ZIP tests cover all six permutations of three tied names, identical/different bytes, and immediate/implicit-relative child paths.

  • Preserve relocation neutrality and distinguish a rename between collating-equal names.

  • Exact legacy identity controls cover ordinary, empty, explicit nested, and non-tied Unicode directories.

  • Direct comparator tests cover reflexivity, lexical antisymmetry/transitivity across the tied subset, and exact preservation of non-tied collation results.

  • Baseline 6fa6f1f: four real-ZIP regression cases fail and eight controls pass. Fixed unit/boundary matrix: 18/18 passed.

  • Six real inspect-artifact <zip> --format json CLI executions feed their unmodified inventory Evidence into production comparison: all three reversed-member pairs change only the legitimately different raw ZIP root; directory and file identities remain unchanged.

  • Independent review found no blockers, including supplemental string, nonzero-comparison, tie, transitivity, and shuffled-order checks.

  • Observed, derived, and inferred claims remain distinguishable.

  • Artifact identity, source provenance, and failed attempts remain preserved.

  • Unsupported, incomplete, unavailable, or uncertain outcomes remain visible.

Validation performed

  • npm run check:pr on the reviewed pre-rebase diff (base 6fa6f1f): 1,951 passed, 1 skipped, 40 failed in the known seven native socket suites denied by this sandbox. Failed test titles exactly match the prior verified baseline, with zero additions/removals. Static checks passed; this is not a full local suite pass.
  • Rebased the identical three-file diff onto main 205a977, incorporating #584's verifier-only repair. 34/34 focused tests passed, including that classifier matrix.
  • On tested base 205a977, npm run check:ci and separate npm run docs:check: passed.
  • npm_config_cache=/tmp/rea-npm-cache npm run verify:package: passed, including full packaged setup/CLI/MCP checks.
  • npm pack --dry-run --cache /tmp/rea-npm-cache: passed.
  • Built CLI/comparison probes and git diff --check: passed.
  • Before publication, the identical diff was integrated onto main 6aba6ae after #585/#586 changed unrelated MCP output/native-permission code. 18/18 focused tests and npm run check:fast passed again. The aggregate/package results above remain tied to their stated tested bases.

Compatibility, safety, and release

No schema, hash-envelope, dependency, or release-metadata changes. IDs remain exact for directories without affected ties/descendants under the same collation. Correcting order-dependent directory IDs is intentional.

Local execution was Linux only. No native Windows/macOS, real Hopper/Ghidra, or cross-ICU stability claim is made.

Review checklist

  • One focused outcome with a Conventional Commit title.
  • Reason for no linked issue stated.
  • Baseline reproduction, ordering properties, and compatibility controls included.
  • Existing contracts/docs remain accurate; generated checks pass.
  • Representative CLI/comparison behavior executed.
  • Final diff checked for secrets, unrelated cleanup, and unsupported claims.

🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/morluto/rea/pull/587 **Author:** [@kaoru0822-kitauji](https://github.com/kaoru0822-kitauji) **Created:** 10/5/2026 **Status:** ✅ Merged **Merged:** 10/5/2026 **Merged by:** [@morluto](https://github.com/morluto) **Base:** `main` ← **Head:** `fix/artifact-directory-collation-ties` --- ### 📝 Commits (1) - [`b013fec`](https://github.com/morluto/rea/commit/b013fecf1179c0005c88fa7ac12a53b94cd74b5a) fix(artifacts): break directory child collation ties ### 📊 Changes **3 files changed** (+158 additions, -3 deletions) <details> <summary>View changed files</summary> ➕ `src/application/ArtifactGraphConstruction.test.ts` (+47 -0) 📝 `src/application/ArtifactGraphConstruction.ts` (+12 -3) 📝 `tests/boundary/filesystem/artifactDirectoryIdentity.test.ts` (+99 -0) </details> ### 📄 Description ## Summary Break collation ties when ordering virtual-directory children so equivalent member permutations retain the same directory fingerprint within the same collation environment. No tracking issue: found during real ZIP inventory/comparison testing; no matching dedicated issue or PR was found. This addresses the explicitly deferred equal-collation case from #580. ## Problem and expected behavior Distinct valid names can compare equal under `localeCompare`. For example, `a.txt` and a name with U+200B inserted after `a` both pass path validation but collate equally. The old stable sort retained their archive enumeration order. Reversing only those members changed the verified `pkg` directory ID and made `compare_artifacts` report a spurious directory content/relations change. This also reproduces when the files contain identical bytes, so an artifact-ID tie-breaker would not suffice. ## Change and scope Retain every nonzero result from the existing locale comparator. Only when names collate equally, compare their UTF-16 code units. A small application-internal comparator helper makes that ordering directly testable. The hash shape, child-relative names, and normal non-tied ordering are unchanged. Corrected tie ordering may change affected virtual-directory IDs and propagate to ancestor directory IDs. This is deliberately **not** a cross-locale/ICU identity guarantee or a claim of complete root/inventory/occurrence/edge determinism. No fixed locale or wholesale comparator replacement is introduced, and other sorting sites remain untouched. ## Contract and boundary impact - Semantic owner and earliest changed stage: application graph construction, sorting child records before virtual-directory hashing. - CLI and MCP/tool-catalog contract: unchanged schemas/tools; corrected virtual-directory identities flow into existing inspection/comparison. - Provider, bridge, target-format, or platform compatibility: real ZIP fixtures executed on Linux; no reader or provider changes. - Evidence, artifact, provenance, or reconstruction contract: keep distinct observed names significant; preserve byte identities and unaffected directory fingerprints. Ancestor directory fingerprints can change when an affected child is corrected. - Process execution, authorization, cleanup, or containment impact: none; no extraction, new execution, or validation relaxation. - Generated metadata, package, or installation impact: none. ## Evidence and regression coverage - Real ZIP tests cover all six permutations of three tied names, identical/different bytes, and immediate/implicit-relative child paths. - Preserve relocation neutrality and distinguish a rename between collating-equal names. - Exact legacy identity controls cover ordinary, empty, explicit nested, and non-tied Unicode directories. - Direct comparator tests cover reflexivity, lexical antisymmetry/transitivity across the tied subset, and exact preservation of non-tied collation results. - Baseline `6fa6f1f`: four real-ZIP regression cases fail and eight controls pass. Fixed unit/boundary matrix: **18/18 passed**. - Six real `inspect-artifact <zip> --format json` CLI executions feed their unmodified inventory Evidence into production comparison: all three reversed-member pairs change only the legitimately different raw ZIP root; directory and file identities remain unchanged. - Independent review found no blockers, including supplemental string, nonzero-comparison, tie, transitivity, and shuffled-order checks. - [x] Observed, derived, and inferred claims remain distinguishable. - [x] Artifact identity, source provenance, and failed attempts remain preserved. - [x] Unsupported, incomplete, unavailable, or uncertain outcomes remain visible. ## Validation performed - `npm run check:pr` on the reviewed pre-rebase diff (base `6fa6f1f`): **1,951 passed, 1 skipped, 40 failed** in the known seven native socket suites denied by this sandbox. Failed test titles exactly match the prior verified baseline, with zero additions/removals. Static checks passed; this is not a full local suite pass. - Rebased the identical three-file diff onto main `205a977`, incorporating #584's verifier-only repair. **34/34 focused tests** passed, including that classifier matrix. - On tested base `205a977`, `npm run check:ci` and separate `npm run docs:check`: passed. - `npm_config_cache=/tmp/rea-npm-cache npm run verify:package`: passed, including full packaged setup/CLI/MCP checks. - `npm pack --dry-run --cache /tmp/rea-npm-cache`: passed. - Built CLI/comparison probes and `git diff --check`: passed. - Before publication, the identical diff was integrated onto main `6aba6ae` after #585/#586 changed unrelated MCP output/native-permission code. **18/18 focused tests** and `npm run check:fast` passed again. The aggregate/package results above remain tied to their stated tested bases. ## Compatibility, safety, and release No schema, hash-envelope, dependency, or release-metadata changes. IDs remain exact for directories without affected ties/descendants under the same collation. Correcting order-dependent directory IDs is intentional. Local execution was Linux only. No native Windows/macOS, real Hopper/Ghidra, or cross-ICU stability claim is made. ## Review checklist - [x] One focused outcome with a Conventional Commit title. - [x] Reason for no linked issue stated. - [x] Baseline reproduction, ordering properties, and compatibility controls included. - [x] Existing contracts/docs remain accurate; generated checks pass. - [x] Representative CLI/comparison behavior executed. - [x] Final diff checked for secrets, unrelated cleanup, and unsupported claims. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
bsakaguchi 2026-10-16 21:14:05 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
morluto/rea#2088
No description provided.