Skip to content

Align rename references with deterministic resolution - #51

Merged
callumalpass merged 2 commits into
mainfrom
consolidation/rename-resolution-consistency
Oct 4, 2026
Merged

callumalpass merged 2 commits into
mainfrom
consolidation/rename-resolution-consistency

Conversation

@callumalpass

Copy link
Copy Markdown
Collaborator

Summary

  • make filename-based rename fixtures genuinely filename-based instead of accidentally matching same-valued IDs
  • require rename reference rewriting to follow the merged same-directory / shortest-path / lexical selector
  • retain the separate configured-ID stability fixtures unchanged

Why

The deterministic simple-link contract already selects a winner for duplicate basenames. Rename/reference rewriting must consume that same outcome rather than treating every duplicate basename as ambiguous. Several older filename-rewrite fixtures also assigned IDs identical to basenames, contradicting the configured-ID stability group.

Evidence

  • mdbase-rs Phase 1 implementation passes 1,794/1,794 fixtures with this change
  • independent adversarial matrices cover same-directory, shortest-path, lexical winners/losers, duplicate IDs, stable IDs, aliases, anchors, embeds, target scoping, order independence, and dry-run parity
  • git diff --check

No collection or wire format changes.

callumalpass added a commit that referenced this pull request Oct 4, 2026
Reconciles rc.5 with the open link PRs #49 and #51.

- Chapter 08: the second tiebreaker counts path segments, and no tool may
  choose among duplicate filename matches by scan, index, or storage order.
  A tiebreaker-resolved link is not ambiguous.
- Chapter 12: a rename with reference updating rewrites the links that
  resolved to the renamed record, including tiebreaker-selected filename
  matches, and never rewrites ambiguous links or links to other records.
  The result lists rewrites in references_updated. A rename keeps the
  record's identity, as a detected move does in Chapter 12A.
- Chapter 14, Chapter 13, the changelog, and the release notes follow.
- Conformance: links.filename_tiebreakers and core_write.rename_references,
  with four tiebreaker tests in core/link-ambiguity.yaml and four rename
  tests in the new core/rename-references.yaml (155 rc.5 tests in all).
callumalpass added a commit that referenced this pull request Oct 4, 2026
#61)

* Specify concurrent-edit semantics and reported validity for rc.5

Validity is reported, never guaranteed: checks fall into request and
safety, single-record, and cross-record tiers, and cross-record checks
never block a write made through an engine.

- collection.merge declares conflict, max, min, or union per top-level
  field, with max for lifecycle now/today fields and union for tags and
  uniqueItems arrays by default.
- Update accepts add and remove list operations.
- collection.unique gains enforce: write | report (default report) and
  exact governed-record and comparison-set scope semantics.
- Paths are equivalent under NFC plus full case folding, with a
  deterministic ' (n)' suffix for derived and concurrent collisions.
- A time-dependent or cross-record match.expr loads with a
  nondeterministic_match warning; it becomes an error in 0.3.0 stable.
- Lifecycle has no sequence provider; CEL is the one expression language
  and Obsidian Bases expressions are an adapter dialect.
- New chapter 12A defines record identity without in-file IDs, move
  detection, the three-way record merge with append-append body union,
  and the writer format fidelity rule.
- settings.id_field has no default, path-pattern values may not contain
  '/', and ambiguous IDs resolve to null with ambiguous_link.
- Chapter 13 lists the changes since rc.4 and how engines report the
  tightenings.
- The v0.3 type-file schema gains collection.merge and unique[].enforce,
  and the claim schema gains the merge profile.

* Add the regex profile and body_edits to rc.5

Regex: CEL matches(), JSON Schema pattern, and match.where matches share
one flavor, the mdbase regex profile defined in chapter 10: RE2 syntax
with ASCII-only \d, \w, \s, \b and case folding over Unicode scalar
values, as in regex-lite. Unicode classes, backreferences, and
look-around are invalid_pattern and make a type invalid. JSON Schema
pattern following the profile instead of ECMA-262 is provisional.

Body edits: update accepts body_edits, ranges whose offsets count Unicode
scalar values of a base body identified by a SHA-256 body_base digest,
with optional body_base_text. Edits apply directly to an unchanged body
and otherwise rebase with the chapter 12A body merge; conflicts are found
per line and fail with body_conflict, and a missing base fails with
body_base_unavailable. They are exclusive with body and document and need
no live-collaboration support.

* Add the rc.5 conformance cases to the v0.3 suite

New tests carry since: 0.3.0-rc.5 and changed tests carry
changed: 0.3.0-rc.5. The manifest marks the rc.5 requirements and adds
the merge profile and the merge and watch fixture sets.

- merge/merge.yaml converts the 13 mdbase-next prototype merge fixtures
  into a merge_records format (base + first + second + type declarations
  -> exact merged bytes and conflicts) and adds 24 merge and strategy
  cases; merge/body-edits.yaml covers applying and rebasing body_edits.
- core/paths.yaml, watch/move-detection.yaml, and cel/regex-profile.yaml
  cover path keys and suffixes, move pairing, and ASCII-versus-Unicode
  regex classes.
- Adapter-target suites cover validation tiers, uniqueness modes and
  scope, non-blocking link checks, list operations, format fidelity, path
  collisions, body_edits through update, nondeterministic_match, and the
  id_field and ambiguous-ID rules.
- links.duplicate_id_ambiguous now also expects ambiguous_link.
- scripts/concurrent_edits_model.py is an executable model of the pure
  functions; check_v03_tests.py runs the 95 pure fixtures against it,
  validates the since/changed markers, and checks that the claim schema
  lists the manifest's profiles.

* Add the 0.3.0-rc.5 changelog entry and release notes

The rc.5 entry covers concurrent edits, reported validity, the regex
profile, and body_edits, and folds in the changes made since rc.4 to YAML
document records and Bases, seed type upgrades, and saved-view
identification.

The release notes list the behavior changes, the one existing test whose
expectation changed and the new tests an rc.4 engine fails, the three
choices decided for rc.5 (unsupported patterns invalidate the type,
body-edit conflicts are per line, time-dependent match.expr becomes an
error in 0.3.0 stable), and the remaining provisional choices.

* Pin filename tiebreakers and rename reference updating for rc.5

Reconciles rc.5 with the open link PRs #49 and #51.

- Chapter 08: the second tiebreaker counts path segments, and no tool may
  choose among duplicate filename matches by scan, index, or storage order.
  A tiebreaker-resolved link is not ambiguous.
- Chapter 12: a rename with reference updating rewrites the links that
  resolved to the renamed record, including tiebreaker-selected filename
  matches, and never rewrites ambiguous links or links to other records.
  The result lists rewrites in references_updated. A rename keeps the
  record's identity, as a detected move does in Chapter 12A.
- Chapter 14, Chapter 13, the changelog, and the release notes follow.
- Conformance: links.filename_tiebreakers and core_write.rename_references,
  with four tiebreaker tests in core/link-ambiguity.yaml and four rename
  tests in the new core/rename-references.yaml (155 rc.5 tests in all).
@callumalpass
callumalpass merged commit 329de55 into main Oct 4, 2026
20 checks passed
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.

1 participant