Skip to content

Bugfix: type-scoped context activation resolves against the active context only - #41

Merged
skydudie merged 1 commit into
mainfrom
fix/type-scoped-lookup-spec-strict
Aug 13, 2026
Merged

Bugfix: type-scoped context activation resolves against the active context only#41
skydudie merged 1 commit into
mainfrom
fix/type-scoped-lookup-spec-strict

Conversation

@skydudie

@skydudie skydudie commented Aug 13, 2026

Copy link
Copy Markdown
Contributor

Proposed changes

Problem — the two spec deviations left in Expansion::activateTypeScopedContexts() after #38:

  1. documentBase fallback: a type-scoped context defined only at the document level could still activate inside a node whose context had been reset. In the VC 2.0 verifiableCredential @context: null isolation shape, a presentation-level type-scoped context (Individual) leaked into the isolated embedded credential and emitted a quad no conformant processor derives:
    + <did:example:subject-456> <https://vocab.example.org/credentials#fullName> "Jane Citizen" _:b0 .
    
    (the exact diff vs jsonld.js from the vc-context-null-isolation interop case, which was listed as a known deviation in Test: cross-implementation interop corpus (jsonld.js RDFC-1.0 goldens) #40). Notably the Individual type quad itself was not emitted — the scoped context activated for a type that couldn't even expand to an IRI there.
  2. findTypeDefRecursive(): the recursive walk through nested @context entries in the document context. Dead weight since Bugfix: Type-scoped context lookup ignores the active context #38 — its stated use case (a type like DataIntegrityProof defined inside an imported security context) is handled by property-scoped context activation, which has already made the type visible in the active context by the time the typed node is entered.

Fix — per JSON-LD 1.1 exp. §5.5 step 11, the type resolves against the active context (the type-scoped snapshot) and nothing else. Both fallbacks removed; net −54/+? lines in Expansion.php.

Evidence the fallbacks were dead weight (beyond the fixed case)

  • W3C suite unchanged: 1287 passed, 15 xfail-skipped — zero regressions across expand/compact/flatten/toRdf/fromRdf/frame.
  • Full unit suite: the only test that changed behavior was the interop xfail guard, which flipped green the moment the fallback was removed — exactly as designed in Test: cross-implementation interop corpus (jsonld.js RDFC-1.0 goldens) #40 — and is delisted here (INTEROP_KNOWN_DEVIATIONS is now empty).

Tests

  • New expansion unit test pinning the isolation behavior (document-level type-scoped context must NOT activate after a property-scoped @context: null reset; the unexpandable type stays "Thing", label drops). Expectations generated with jsonld.js 8.3.3; confirmed red against main's Expansion.php.
  • vc-context-null-isolation interop case now passes for real: our canonical N-Quads for the VC 2.0 isolation shape are dataset-identical to jsonld.js.
  • Unit: 343 passed, 0 skipped (was 341 + 1 skip). Pint + PHPStan (max) clean.

Jira ticket link

  • N/A

Checklist

  • New unit test red on main, green with the fix
  • W3C conformance suite unchanged (verified in Linux container; CI covers it)
  • Interop corpus fully green, known-deviations list emptied
  • Pint + PHPStan pass

Further comments

@skydudie skydudie self-assigned this Aug 13, 2026
@skydudie skydudie added bug Something isn't working enhancement New feature or request labels Aug 13, 2026
…t only

Removes the two spec deviations left in
Expansion::activateTypeScopedContexts() after #38:

- the documentBase fallback, which let a DOCUMENT-level type-scoped
  context activate inside a node whose context had been reset — for the
  VC 2.0 `verifiableCredential` @context:null isolation shape this
  leaked presentation-level scoped terms into the isolated credential,
  emitting quads no conformant processor derives (one extra fullName
  quad vs jsonld.js in the tests/Interop vc-context-null-isolation
  case);
- findTypeDefRecursive(), the recursive walk through nested @context
  entries. Dead weight since #38: its use case (a type such as
  DataIntegrityProof defined inside an imported security context) is
  covered by property-scoped context activation, which has already made
  the type visible in the active context by the time the typed node is
  entered.

Per JSON-LD 1.1 §5.5 step 11 the type resolves against the active
(type-scoped snapshot) context and nothing else.

- vc-context-null-isolation delisted from INTEROP_KNOWN_DEVIATIONS (its
  xfail guard flipped as designed the moment the fallback was removed).
- New expansion unit test pins the isolation behavior; expectations
  generated with jsonld.js 8.3.3; red on the pre-fix source.

Unit 343 passed (0 skipped, was 1); W3C unchanged (1287 passed,
15 xfail-skipped); pint + PHPStan (max) clean.
@skydudie
skydudie force-pushed the fix/type-scoped-lookup-spec-strict branch from e68240f to 47d5e0a Compare August 13, 2026 07:24
@skydudie
skydudie merged commit 8fb062d into main Aug 13, 2026
5 checks passed
@skydudie
skydudie deleted the fix/type-scoped-lookup-spec-strict branch August 13, 2026 07:26
skydudie added a commit that referenced this pull request Aug 13, 2026
## Proposed changes

Prepares the repo for submission to the [W3C JSON-LD 1.1 implementation
report](https://w3c.github.io/json-ld-api/reports/) (we'd be the first
PHP implementation listed) and retires the development-phase framing
from the README.

**README rewrite**
- Removed the scaffolding: placeholder badge comments ("wired up in PR
1.2 / Phase 6"), the `Scope (delivered)` checkbox tracker (its content
is the conformance matrix), and the v0.42.0 comparison-methodology
footnotes.
- Restructured as: highlights → installation → usage → conformance →
interoperability → development notes. New sections for the interop
corpus (#40) and the implementation report.
- Fixed the install instruction (`composer require
accredifysg/php-json-ld:^1.0` → unconstrained; we're on 2.1.0).
- Conformance matrix refreshed against the current W3C suite: fromRdf is
now 50/54 (upstream added `#t0028`, which we pass), totals
**1,287/1,302**.

**W3C EARL implementation report**
- `reports/php-json-ld-earl.ttl` — generated from the v2.1.0 W3C suite
run: **1,275 assertions, 1,262 passed, 13 failed** (failures reported
explicitly, unlike most submissions). `specVersion: json-ld-1.0` tests
are excluded to match the consolidated report's JSON-LD 1.1 scope (same
as prior submissions, e.g. w3c/json-ld-api#652).
- `scripts/generate-earl-report.php` — regenerates the report from a
`--log-junit` run of the W3C testsuite, so future releases refresh it
with two commands (documented in the README). Verified: the report
ingests into the W3C `earl-report` toolchain with zero warnings and
renders as *PHP-JSON-LD / Accredify / PHP*.

**Supporting changes**
- `tests/w3c` submodule bumped to current upstream head, so `composer
test:w3c` reproduces the README/report numbers exactly (previously
pinned pre-`#t0028`: 1,286/1,301).
- CHANGELOG: backfilled the missing **2.1.0** section (the tag was cut
without one — it covers #38/#39/#40/#41) and recorded this PR's
additions under Unreleased.

## Jira ticket link

- N/A

## Checklist

- [x] Unit suite green (346 passed, includes interop corpus)
- [x] W3C suite green against the bumped submodule (1,287 passed / 15
xfail-skipped)
- [x] Pint + PHPStan pass
- [x] EARL report validates (rdflib) and ingests into the earl-report
gem with zero warnings

## Further comments

- Once this merges, the identical `.ttl` gets submitted as a PR to
`w3c/json-ld-api` (branch already prepared), giving the submission a
canonical in-repo artifact to reference.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant