diff --git a/schemas/v1.2-dev/schema.yaml b/schemas/v1.2-dev/schema.yaml
index 4891415..cb393c3 100644
--- a/schemas/v1.2-dev/schema.yaml
+++ b/schemas/v1.2-dev/schema.yaml
@@ -6,11 +6,18 @@ properties:
overlay:
type: string
pattern: ^1\.2\.\d+$
+ $self:
+ type: string
+ format: uri-reference
+ $comment: MUST NOT contain a fragment
+ pattern: "^[^#]*$"
info:
$ref: "#/$defs/info-object"
extends:
type: string
format: uri-reference
+ $comment: MUST NOT contain a fragment
+ pattern: "^[^#]*$"
actions:
type: array
minItems: 1
diff --git a/tests/v1.2-dev/fail/extends-with-fragment.yaml b/tests/v1.2-dev/fail/extends-with-fragment.yaml
new file mode 100644
index 0000000..59a6841
--- /dev/null
+++ b/tests/v1.2-dev/fail/extends-with-fragment.yaml
@@ -0,0 +1,7 @@
+overlay: 1.2.0
+info:
+ title: Invalid extends with fragment
+ version: 1.0.0
+extends: https://api.example.com/openapi/petstore.yaml#/paths/~1pets
+actions:
+ - target: '$'
diff --git a/tests/v1.2-dev/fail/self-with-fragment.yaml b/tests/v1.2-dev/fail/self-with-fragment.yaml
new file mode 100644
index 0000000..c98a981
--- /dev/null
+++ b/tests/v1.2-dev/fail/self-with-fragment.yaml
@@ -0,0 +1,7 @@
+overlay: 1.2.0
+$self: https://example.com/overlays/petstore.overlay.yaml#fragment
+info:
+ title: Invalid self with fragment
+ version: 1.0.0
+actions:
+ - target: '$'
diff --git a/tests/v1.2-dev/pass/self-and-extends-identifier.yaml b/tests/v1.2-dev/pass/self-and-extends-identifier.yaml
new file mode 100644
index 0000000..862f4ac
--- /dev/null
+++ b/tests/v1.2-dev/pass/self-and-extends-identifier.yaml
@@ -0,0 +1,10 @@
+overlay: 1.2.0
+$self: https://example.com/overlays/petstore.overlay.yaml
+info:
+ title: Overlay with identifier-based extends
+ version: 1.0.0
+extends: https://api.example.com/openapi/petstore.yaml
+actions:
+ - target: '$.info'
+ update:
+ x-overlay-applied: true
diff --git a/tests/v1.2-dev/pass/self-with-relative-extends.yaml b/tests/v1.2-dev/pass/self-with-relative-extends.yaml
new file mode 100644
index 0000000..f512f58
--- /dev/null
+++ b/tests/v1.2-dev/pass/self-with-relative-extends.yaml
@@ -0,0 +1,10 @@
+overlay: 1.2.0
+$self: https://example.com/overlays/petstore.overlay.yaml
+info:
+ title: Overlay with relative extends
+ version: 1.0.0
+extends: ../openapi/petstore.yaml
+actions:
+ - target: '$.info'
+ update:
+ x-overlay-applied: true
diff --git a/versions/1.2.0-dev.md b/versions/1.2.0-dev.md
index 7f771e7..0c529b2 100644
--- a/versions/1.2.0-dev.md
+++ b/versions/1.2.0-dev.md
@@ -65,9 +65,38 @@ Where Overlay tooling renders rich text it MUST support, at a minimum, markdown
While the framing of CommonMark 0.27 as a minimum requirement means that tooling MAY choose to implement extensions on top of it, note that any such extensions are by definition implementation-defined and will not be interoperable.
Overlay Description authors SHOULD consider how text using such extensions will be rendered by tools that offer only the minimum support.
+### Parsing Documents
+
+Implementations MUST NOT treat an `extends` value as unresolvable before checking all possible target [[OpenAPI]] Description documents provided to the implementation.
+
+To ensure portability, when a target [[OpenAPI]] Description defines `$self`, the Overlay's `extends` value SHOULD match the target's `$self` URI.
+Implementations MUST examine all available target documents for matching `$self` values before concluding that no document matches the `extends` URI.
+
### Relative References in URIs
-Unless specified otherwise, all fields that are URI references MAY be relative references as defined by [RFC3986](https://tools.ietf.org/html/rfc3986#section-4.2).
+URIs used in an Overlay document, including `$self` and `extends`, are identifiers, and not necessarily locators (URLs).
+
+Unless specified otherwise, all fields that are URI references MAY be relative references as defined by [RFC3986 Section 4.2](https://tools.ietf.org/html/rfc3986#section-4.2).
+
+#### Establishing the Base URI
+
+Relative URI references are resolved using the appropriate base URI, which MUST be determined in accordance with [RFC3986 Section 5.1.1 - 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.1).
+
+The base URI for resolving relative references within an Overlay document is determined as follows:
+
+- If the [`$self`](#overlay-self) field is present and is an absolute URI, the base URI is the `$self` URI (per [RFC3986 Section 5.1.1](https://tools.ietf.org/html/rfc3986#section-5.1.1): Base URI Embedded in Content).
+- If the [`$self`](#overlay-self) field is present and is a relative URI-reference, it MUST first be resolved against the next possible base URI source per [RFC3986 Section 5.1.2 - 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.2) before being used as the base URI for resolving other relative references.
+- If the [`$self`](#overlay-self) field is not present, the base URI MUST be determined from the next possible base URI source per [RFC3986 Section 5.1.2 - 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.2). The most common base URI source in this case is the retrieval URI of the Overlay document (per [RFC3986 Section 5.1.3](https://tools.ietf.org/html/rfc3986#section-5.1.3)), though other sources such as encapsulating entities ([RFC3986 Section 5.1.2](https://tools.ietf.org/html/rfc3986#section-5.1.2)) or application-specific defaults ([RFC3986 Section 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.4)) MAY apply.
+
+#### Resolving URI Fragments
+
+Where a URI appears in contexts such as CommonMark hyperlinks within `description` fields and contains a fragment identifier, the fragment MUST be resolved per the fragment resolution mechanism of the referenced document.
+
+For Overlay Object fields that identify whole documents (`$self` and `extends`), fragment identifiers MUST NOT be used.
+
+#### Relative URI References in CommonMark Fields
+
+Relative references in CommonMark hyperlinks (such as those in `description` fields) are resolved in their rendered context, which might differ from the context of the Overlay document.
### Schema
@@ -82,6 +111,7 @@ This is the root object of the [Overlay](#overlay).
| Field Name | Type | Description |
| ---- | :----: | ---- |
| overlay | `string` | **REQUIRED**. This string MUST be the [version number](#versions) of the Overlay Specification that the Overlay document uses. The `overlay` field SHOULD be used by tooling to interpret the Overlay document. |
+| $self | `string` | A URI-reference for the Overlay document. This string MUST be in the form of a URI-reference as defined by [RFC3986 Section 4.1](https://tools.ietf.org/html/rfc3986#section-4.1). When present, this field provides the self-assigned URI of this Overlay document, which also serves as its base URI in accordance with [RFC3986 Section 5.1.1](https://tools.ietf.org/html/rfc3986#section-5.1.1) for resolving relative references within this document. The `$self` URI MUST NOT contain a fragment identifier. Overlay documents MAY include a `$self` field to ensure portable, unambiguous reference resolution. |
| info | [Info Object](#info-object) | **REQUIRED**. Provides metadata about the Overlay. The metadata MAY be used by tooling as required. |
| extends | `string` | URI reference that identifies the target document (such as an [[OpenAPI]] document) this overlay applies to. |
| actions | [[Action Object](#action-object)] | **REQUIRED** An ordered list of actions to be applied to the target document. The array MUST contain at least one value. |
@@ -90,29 +120,46 @@ This object MAY be extended with [Specification Extensions](#specification-exten
The list of actions MUST be applied in sequential order to ensure a consistent outcome. Actions are applied to the result of the previous action. This enables objects to be deleted in one action and then re-created in a subsequent action, for example.
-The `extends` property can be used to indicate that the Overlay was designed to update a specific [[OpenAPI]] document. Where no `extends` is provided it is the responsibility of tooling to apply the Overlay document to the appropriate OpenAPI document(s).
+The `extends` property can be used to indicate that the Overlay was designed to update a specific [[OpenAPI]] description.
+Where no `extends` is provided it is the responsibility of tooling to apply the Overlay document to the appropriate OpenAPI description(s).
+
+In the following example, the Overlay identifies a target OpenAPI description using an absolute URI:
+
+```yaml
+overlay: 1.2.0
+info:
+ title: Overlay for the Tic Tac Toe API document
+ version: 1.0.0
+extends: 'https://api.example.com/openapi/tictactoe.yaml'
+...
+```
-In the following example the `extends` property specifies that the overlay is designed to update the OpenAPI Tic Tac Toe example document, identified by an absolute URI.
+In the following example, the Overlay document also includes `$self`, which establishes the document's identity and base URI:
```yaml
overlay: 1.2.0
+$self: 'https://example.com/overlays/tictactoe.overlay.yaml'
info:
title: Overlay for the Tic Tac Toe API document
version: 1.0.0
-extends: 'https://raw.githubusercontent.com/OAI/learn.openapis.org/refs/heads/main/examples/v3.1/tictactoe.yaml'
+extends: 'https://api.example.com/openapi/tictactoe.yaml'
...
```
The `extends` property can also specify a relative URI reference.
+Relative `extends` values are resolved using the base URI rules in [Relative References in URIs](#relative-references-in-uris):
```yaml
overlay: 1.2.0
+$self: 'https://example.com/overlays/tictactoe.overlay.yaml'
info:
title: Overlay for the Tic Tac Toe API document
version: 1.0.0
-extends: './tictactoe.yaml'
+extends: '../openapi/tictactoe.yaml'
```
+With the above Overlay document, `extends` resolves to `https://example.com/openapi/tictactoe.yaml`.
+
#### Info Object
The object provides metadata about the Overlay.
@@ -594,3 +641,144 @@ Some formats, like [YAML](https://yaml.org/) or [JSONC](https://jsonc.org/), sup
| 1.2.0 | TBD | Release of the Overlay Specification 1.2.0 |
| 1.1.0 | 2026-01-14 | Release of the Overlay Specification 1.1.0 |
| 1.0.0 | 2024-10-17 | First release of the Overlay Specification |
+
+## Appendix B: Examples of Base URI Determination and Identifier Resolution
+
+This appendix provides concrete examples demonstrating how the [`$self`](#overlay-self) field, Source Description URLs, and relative references work together across different deployment scenarios.
+
+### Base URI Within Content (Using `$self`)
+
+Assume the following Overlay document is retrieved from `file:///Users/dev/projects/overlays/purchase.overlay.yaml`:
+
+```yaml
+overlay: 1.2.0
+$self: https://example.com/overlays/purchase.overlay.yaml
+info:
+ title: Purchase overlay
+ version: 1.0.0
+extends: ../openapi/petstore.yaml
+actions:
+ - target: '$.info'
+ update:
+ x-overlay: purchase
+```
+
+The relative `extends` URI `../openapi/petstore.yaml` resolves against the `$self` base URI `https://example.com/overlays/purchase.overlay.yaml`, producing `https://example.com/openapi/petstore.yaml`, regardless of the retrieval URI.
+
+### Base URI From the Retrieval URI (No `$self`)
+
+If the same Overlay document does not define `$self`:
+
+```yaml
+overlay: 1.2.0
+info:
+ title: Purchase overlay
+ version: 1.0.0
+extends: ../openapi/petstore.yaml
+actions:
+ - target: '$.info'
+ update:
+ x-overlay: purchase
+```
+
+Retrieved from `file:///Users/dev/projects/overlays/purchase.overlay.yaml`, the relative `extends` URI resolves to `file:///Users/dev/projects/openapi/petstore.yaml`.
+
+### Base URI From Encapsulating Entity
+
+Per [RFC3986 Section 5.1.2](https://tools.ietf.org/html/rfc3986#section-5.1.2), the base URI can be provided by an encapsulating entity. For example, in a `multipart/related` response where an Overlay document is embedded:
+
+```http
+Content-Type: multipart/related; boundary=example; type=application/json
+
+--example
+Content-Type: application/json
+Content-Location: https://example.com/overlays/purchase.overlay.json
+
+{
+ "overlay": "1.2.0",
+ "info": {"title": "Purchase overlay", "version": "1.0.0"},
+ "extends": "../openapi/petstore.json",
+ "actions": [
+ {
+ "target": "$.info",
+ "update": {"x-overlay": "purchase"}
+ }
+ ]
+}
+--example--
+```
+
+The `Content-Location` header provides the base URI (`https://example.com/overlays/purchase.overlay.json`), so `../openapi/petstore.json` resolves to `https://example.com/openapi/petstore.json` even without a `$self` field.
+
+### Application-Specific Default Base URI
+
+Per [RFC3986 Section 5.1.4](https://tools.ietf.org/html/rfc3986#section-5.1.4), applications may define default base URIs. For documents loaded without explicit retrieval URIs (e.g., from a database), implementations typically generate a unique base URI per document using a fixed prefix plus a unique identifier.
+
+For example, an API management platform might construct base URIs as `https://overlays.example.com/{uuid}` for each document:
+
+```yaml
+overlay: 1.2.0
+# No $self field
+# Loaded from database, assigned base URI: https://overlays.example.com/a7b3c4d5
+info:
+ title: Purchase overlay
+ version: 1.0.0
+extends: specs/petstore.yaml # Resolves using application default
+actions:
+ - target: '$.info'
+ update:
+ x-overlay: purchase
+```
+
+If the application assigns base URI `https://overlays.example.com/a7b3c4d5` to this document, then `specs/petstore.yaml` resolves to `https://overlays.example.com/specs/petstore.yaml`.
+
+### Resolving Relative `$self`
+
+When `$self` is itself a relative URI-reference, it must be resolved before being used as a base URI:
+
+```yaml
+overlay: 1.2.0
+$self: overlays/purchase.overlay.yaml
+info:
+ title: Purchase overlay
+ version: 1.0.0
+extends: ../openapi/petstore.yaml
+actions:
+ - target: '$.info'
+ update:
+ x-overlay: purchase
+```
+
+Retrieved from `https://example.com/v2/api-description.yaml`:
+
+1. First, resolve the `$self` relative reference `overlays/purchase.overlay.yaml` against the retrieval URI `https://example.com/v2/api-description.yaml`, which resolves to `https://example.com/v2/overlays/purchase.overlay.yaml` per [RFC3986 Section 5.2](https://tools.ietf.org/html/rfc3986#section-5.2).
+2. Then resolve the `extends` relative reference `../openapi/petstore.yaml` against the resolved `$self` base URI `https://example.com/v2/overlays/purchase.overlay.yaml`, which resolves to `https://example.com/v2/openapi/petstore.yaml`.
+
+### Why Potential Target Documents Should Be Checked for `$self`
+
+An Overlay may be given this `extends` value:
+
+```yaml
+overlay: 1.2.0
+info:
+ title: Overlay for approved API description
+ version: 1.0.0
+extends: https://apis.example.com/approved/petstore.yaml
+actions:
+ - target: '$.info'
+ update:
+ x-overlay: approved
+```
+
+A candidate target OpenAPI description might be retrieved from `https://cdn.example.net/mirror/petstore.yaml` while declaring:
+
+```yaml
+openapi: 3.2.0
+$self: https://apis.example.com/approved/petstore.yaml
+info:
+ title: Petstore
+ version: 1.0.0
+paths: {}
+```
+
+Because `extends` is identifier-based, the match succeeds using the target description's `$self` URI, even though retrieval occurred from a different location.