Skip to content

[AIT-1092] chore(uts): reconcile LiveObjects (objects) test specs with main spec#499

Open
sacOO7 wants to merge 1 commit into
uts-liveobjectsfrom
chore/fix-uts-liveobjects-spec
Open

[AIT-1092] chore(uts): reconcile LiveObjects (objects) test specs with main spec#499
sacOO7 wants to merge 1 commit into
uts-liveobjectsfrom
chore/fix-uts-liveobjects-spec

Conversation

@sacOO7

@sacOO7 sacOO7 commented Jun 30, 2026

Copy link
Copy Markdown
Collaborator

Intent

The canonical LiveObjects spec (specifications/objects-features.md) on main has moved ahead of the version the uts/objects test specs were originally written against. This PR reconciles the test specs with main and folds in the test-correctness fixes identified during the objects UTS audit, so the derived SDK tests are generated from a spec-faithful, internally-consistent source.

Source of truth: objects-features.md on main, cross-checked against the ably-js liveobjects implementation. Where ably-js naming differs from the spec, the spec wins.

Scope is limited to uts/objects. No SDK code or feature behaviour changes — these are test-specification (pseudocode) updates only.


What changed

1. Internal CRDT naming → InternalLiveMap / InternalLiveCounter

main renames the internal CRDT graph objects to disambiguate them from the public API and the create-blueprints. Applied across 271 references (constructions, IS assertions, .diff, #method delegations, and prose).

The four CRDT spec files were renamed to match (the skill resolver derives the test class name from the filename, so generated classes become InternalLive* automatically):

Old New
unit/live_counter.md unit/internal_live_counter.md
unit/live_map.md unit/internal_live_map.md
unit/live_counter_api.md unit/internal_live_counter_api.md
unit/live_map_api.md unit/internal_live_map_api.md

Left unchanged on purpose: blueprint .create() factories, public PathObject/Instance, LiveObject (base), and LiveMapUpdate/LiveCounterUpdate/LiveMapValue.

2. get() precondition: RTO23bRTO23e (ensure-active-channel)

RTO23b (throw 90001 on DETACHED/FAILED) was replaced by RTO23e (perform ensure-active-channel, RTL33):

Channel state Before (RTO23b) After (RTO23e / RTL33)
DETACHED throws 90001 re-attaches and resolves with the root PathObject
FAILED throws 90001 rejects 90001 (via RTL33c)

Read/subscribe access methods are a separate check (RTO25b, still 90001 on DETACHED/FAILED) — verified against ably-js (get()ensureAttached(); access methods → throwIfInvalidAccessApiConfiguration()).

3. Blueprint value types → LiveMap / LiveCounter

LiveMapValueType / LiveCounterValueType renamed to LiveMap / LiveCounter (immutable blueprints with static .create()), matching main and the ably-js public exports (LiveMapValueType as LiveMap, LiveCounterValueType as LiveCounter).

4. RTO25 / RTO26 preconditions consolidated into realtime_object.md

The spec centralised the per-method preconditions into RTO25 (access) / RTO26 (write), and the per-method clauses now read "replaced by RTO25/RTO26". Eight notes pointed readers to two files (rto25_access_preconditions.md, rto26_write_preconditions.md) that never existed.

  • Hosted the precondition tests as dedicated sections inside realtime_object.md (RTO25a, RTO25b ×2, RTO26a, RTO26b ×2, RTO26c), grouped after the get() tests.
  • Repointed all 8 notes to realtime_object.md with section qualifiers.
  • Dropped the mislabeled RTO25b-via-get() tests; the genuine RTO25b tests now exercise a real access method (root.keys()) on DETACHED/FAILED.

5. public_object_message: spec-neutral derivedFrom

Replaced the ably-js-private field name _derivedFrom with derivedFrom (+ a comment): the spec (RTLCV4g5/RTLMV4j5) keeps the retained CounterCreate/MapCreate local-only and unnamed, so the UTS pseudocode should not borrow an SDK-internal field name. The assertions already read spec-present PAOOP fields only.

6. Test-correctness fixes (objects UTS audit)

Independent of the main delta, folded in here:

  • Quiescence-barrier pattern for negative subscription assertions (a control listener on a live object, so "no event" is provable).
  • Tombstone / echo-dedup handling; map-clear (RTLM24) and LWW-reject (RTLM9b) semantics; path depth-coverage (RTO24b2a1) fixes.
  • ack_serial helper + exposed SITE_CODE in standard_test_pool; explicit REST per-op cardinality; assorted spec-ID and expected-event corrections (e.g. RTPO13c5, RTPO3c292005, RTINS16g).

Validation

  • diff of working-copy vs main objects-features.md, normalising the two renames to isolate the single behavioural change (RTO23bRTO23e).
  • Exhaustive token-level sweep confirming 0 stray/broken renames; LiveObject preserved; every asserted internal field is spec-named.
  • Cross-checked get() / access / write precondition behaviour and the value-type exports against ably-js.
  • Re-verified the consolidated RTO25/RTO26 sections are structurally complete and all 8 references resolve.

Notes / out of scope

  • SUSPENDED write-precondition test is not added — RTO26b covers DETACHED/FAILED/SUSPENDED but the suite only tests DETACHED/FAILED. This is a pre-existing coverage gap, not a regression; happy to add RTO26b/write-throws-suspended-0 if wanted.
  • Review/tracking docs in the parent uts/ directory still reference the old filenames; they are historical records and were intentionally left untouched.

@github-actions github-actions Bot temporarily deployed to staging/pull/499 June 30, 2026 19:22 Inactive
Align the uts/objects test specs with the canonical objects-features.md
on main, and fold in the test-correctness fixes from the objects UTS audit.

Reconciliation with main:
- Rename the internal CRDT type LiveMap/LiveCounter -> InternalLiveMap/
  InternalLiveCounter (271 refs), and rename the four CRDT spec files to
  internal_live_*.md, repointing all cross-references. Blueprint
  .create() factories, public PathObject/Instance, and LiveMapUpdate/
  LiveMapValue are deliberately left unchanged.
- get() precondition RTO23b -> RTO23e: get() now performs
  ensure-active-channel (RTL33) -- re-attaches on DETACHED, rejects 90001
  only on FAILED -- instead of unconditionally throwing 90001.
- Rename blueprint value types LiveMapValueType/LiveCounterValueType ->
  LiveMap/LiveCounter (static .create() factories), matching main.
- Consolidate RTO25 (access) / RTO26 (write) preconditions as dedicated
  sections in realtime_object.md, fixing 8 references to two precondition
  files that never existed; drop the mislabeled RTO25b-via-get() tests.
- public_object_message: replace the ably-js-private _derivedFrom with a
  spec-neutral derivedFrom (RTLCV4g5/RTLMV4j5 keep this retained Create
  local-only and unnamed).

Test-correctness fixes (objects UTS audit):
- Quiescence-barrier pattern for negative subscription assertions.
- Tombstone / echo-dedup handling; map-clear (RTLM24) and LWW-reject
  (RTLM9b) semantics; path depth-coverage (RTO24b2a1) fixes.
- ACK-serial helper + SITE_CODE in standard_test_pool; explicit REST
  per-op cardinality; assorted spec-ID and expected-event corrections.

Validated against main objects-features.md and cross-checked with ably-js;
spec naming is preferred over ably-js where the two differ.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the uts/objects test-spec pseudocode to match the newer canonical LiveObjects spec terminology and behaviors, ensuring derived SDK tests are generated from spec-faithful, internally consistent inputs.

Changes:

  • Renames internal CRDT types and related specs to InternalLiveMap / InternalLiveCounter, while keeping public API/blueprint naming intact.
  • Updates RealtimeObject.get() preconditions/behavior to the ensure-active-channel flow (reattach on DETACHED; reject on FAILED), and consolidates RTO25/RTO26 precondition tests into realtime_object.md.
  • Improves test correctness and determinism (negative-assertion quiescence barriers, ack serial helpers, siteCode exposure, and several behavioral expectation fixes).

Reviewed changes

Copilot reviewed 18 out of 18 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
uts/objects/unit/value_types.md Renames blueprint value types to LiveCounter/LiveMap and updates assertions/requirements accordingly.
uts/objects/unit/realtime_object.md Updates get() behavior to ensure-active-channel semantics; consolidates RTO25/RTO26 precondition tests; adds sync-wait correctness assertions.
uts/objects/unit/public_object_message.md Renames _derivedFrom to spec-neutral derivedFrom in local-only retained create metadata.
uts/objects/unit/path_object.md Updates internal CRDT naming in delegation/prose/spec references.
uts/objects/unit/path_object_subscribe.md Adds quiescence-control patterns to make negative subscription assertions non-flaky; adjusts depth/path stimuli.
uts/objects/unit/path_object_mutations.md Updates internal CRDT naming and blueprint type names for write delegation tests.
uts/objects/unit/parent_references.md Updates internal CRDT naming for parentReferences and rebuild behavior tests.
uts/objects/unit/objects_pool.md Updates internal CRDT naming in pool initialization/sync logic assertions.
uts/objects/unit/live_object_subscribe.md Adds quiescence barriers and clarifies noop/tombstone subscription behaviors.
uts/objects/unit/internal_live_map.md Renames and updates InternalLiveMap CRDT tests; adjusts several semantics explanations/assertions.
uts/objects/unit/internal_live_map_api.md Renames map API tests and repoints precondition-test references to consolidated sections.
uts/objects/unit/internal_live_counter.md Renames and updates InternalLiveCounter CRDT tests.
uts/objects/unit/internal_live_counter_api.md Renames counter API tests and repoints precondition-test references to consolidated sections.
uts/objects/unit/instance.md Updates internal CRDT naming for Instance delegation and event assertions; adds quiescence control for unsubscribe tests.
uts/objects/PLAN.md Updates architecture summary and file plan to reflect new naming and consolidated precondition sections.
uts/objects/integration/objects_sync_test.md Updates integration test prose to InternalLiveMap naming.
uts/objects/integration/objects_lifecycle_test.md Updates integration test prose for InternalLive* naming and blueprint type naming.
uts/objects/helpers/standard_test_pool.md Exposes canonical SITE_CODE and ack_serial; documents negative-assertion quiescence; updates naming.
Comments suppressed due to low confidence (1)

uts/objects/unit/internal_live_map.md:1301

  • Grammar: use “an InternalLiveMap” (vowel sound) instead of “a InternalLiveMap”.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

**Test ID**: `objects/unit/RTPO3a1/intermediate-not-map-0`

**Spec requirement:** Current object must be a LiveMap. If not, resolution fails.
**Spec requirement:** Current object must be a InternalLiveMap. If not, resolution fails.
**Test ID**: `objects/unit/RTINS12d/set-non-map-throws-0`

**Spec requirement:** If the wrapped value is not a LiveMap, throw ErrorInfo with code 92007.
**Spec requirement:** If the wrapped value is not a InternalLiveMap, throw ErrorInfo with code 92007.
**Test ID**: `objects/unit/RTINS14d/increment-non-counter-throws-0`

**Spec requirement:** If the wrapped value is not a LiveCounter, throw ErrorInfo with code 92007.
**Spec requirement:** If the wrapped value is not a InternalLiveCounter, throw ErrorInfo with code 92007.
| RTO3a | ObjectsPool is Dict<String, LiveObject> |
| RTO3b | Must always contain a LiveMap with id "root" |
| RTO3b1 | On initialization, create zero-value LiveMap with objectId "root" |
| RTO3b | Must always contain a InternalLiveMap with id "root" |
Comment on lines 617 to 619
ProtocolMessage(action: CONNECTED, connectionDetails: {
connectionId: "conn-1", connectionKey: "key-1", siteCode: "test-site",
objectsGCGracePeriod: 86400000
connectionId: "conn-1", connectionKey: "key-1", siteCode: "test-site"
})
@sacOO7 sacOO7 changed the title chore(uts): reconcile LiveObjects (objects) test specs with main spec [AIT-1092] chore(uts): reconcile LiveObjects (objects) test specs with main spec Jul 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants