Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Resource contracts and acceptance:
- [Responsibility acceptance criteria](reference/responsibility-acceptance.md)
- [Decision and Document contracts](reference/decision-and-document-contracts.md)
- [Decision and Document acceptance requirements](reference/decision-and-document-acceptance.md)
- [Supplied source bundle profile](reference/source-bundle-profile.md)
- [Source integration contracts](reference/source-integration-contracts.md)
- [Source integration acceptance requirements](reference/source-integration-acceptance.md)

Expand Down
10 changes: 6 additions & 4 deletions docs/explanation/architecture-resource-roadmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,17 +108,19 @@ are later milestones with explicit acceptance criteria. Native Channel and
DataStore support does not require a source connector, a source overlay,
Specification resources or format-specific compatibility checking.

Native manifest export already exists. Source integration still needs its own
mapping, provenance, reconciliation and export-fidelity contracts; it must
preserve the existing behavioral anchors and exact selections.
Native manifest export already exists. The
[supplied bundle profile](../reference/source-bundle-profile.md) implements strict
byte intake and deterministic digests in Rust core. Source mapping, retained
provenance, reconciliation and export fidelity remain pending; they must preserve
the existing behavioral anchors and exact selections.

The proposed [source integration contract](../reference/source-integration-contracts.md)
defines a native-first boundary for immutable supplied bundles, explicit
identity and version mappings, provenance and guarded reconciliation. Its
[acceptance requirements](../reference/source-integration-acceptance.md) distinguish
same-store reapply from migration into a new store, where incarnation-bound
selectors require explicit rebinding. These are proposed contracts; source
records, reconciliation operations and executable acceptance are not implemented.
records, reconciliation operations and their executable acceptance remain pending.
Remote connectors and additional format compilers remain separate milestones.

## Atlas Linter comes after the architecture resources
Expand Down
129 changes: 129 additions & 0 deletions docs/reference/source-bundle-profile.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
# Supplied source bundle profile

Status: implemented in the Rust core `source_bundle` module. This intake boundary
validates supplied bytes and computes digests. Registration, retained snapshots,
source overlays and reconciliation remain proposed in the
[source integration contract](source-integration-contracts.md).

## Inventory JSON

The profile name is `supplied-native-v1` and `profile_revision` is the integer
`1`. The inventory is strict UTF-8 JSON. Field names are case-sensitive; every
field below is required except `coverage`, which defaults to `PARTIAL`.
Unknown fields, duplicate object keys at any depth, wrong types and trailing
JSON values reject. JSON object-key order and whitespace remain original bytes.

```json
{
"profile": "supplied-native-v1",
"profile_revision": 1,
"registration": "registry-a",
"source_version": "revision-A",
"partition": {
"categories": ["model"],
"logical_roots": ["native"],
"selected_keys": []
},
"coverage": "PARTIAL",
"resources": [
{
"key": {"category": "model", "key": "orders"},
"file": "native/model.yaml",
"pointer": {"kind": "yaml", "raw": "#/orders"}
}
],
"relations": [
{
"owner": {"category": "model", "key": "orders"},
"occurrence": "observes-orders",
"role": "observes",
"position": 0,
"target": {"kind": "opaque", "raw": "unresolved-target"},
"file": "native/model.yaml"
}
]
}
```

Registration, source version, category, resource key, occurrence key, pointer
kind and role are opaque case-sensitive strings. They must be nonblank, contain
no Unicode control characters and occupy at most 1,024 UTF-8 bytes. They are
retained without trimming, normalization or native version conversion.

A pointer's `raw` value is any JSON string occupying at most 16,384 decoded UTF-8
bytes. Empty strings and escaped controls are permitted and retained verbatim
as decoded strings; the original JSON spelling remains in `inventory_bytes`.
Pointers are never resolved, fetched or executed. A relation's `position` is an
unsigned 64-bit integer, independent of its array index. Authored array order is
preserved. Resource keys must be unique. Occurrence keys must be unique within
their owner; repeated equal targets with different occurrence keys remain
separate declarations. Each relation owner must occur in `resources`.

## Partition and file locators

`categories` and `logical_roots` must be nonempty unique lists. `selected_keys`
is a unique list of resource-key objects whose categories must be declared.
An empty `selected_keys` list selects all keys within the declared categories
and roots. A nonempty list restricts enumerated resources to those exact keys.
Selected keys may be absent from `resources`, including under `COMPLETE` coverage.
Their absence supplies no deletion authority at this intake boundary.

Every resource and relation `file` must name a supplied file and match a logical
root exactly or begin with that root followed by `/`. Supplied files outside the
roots are permitted as retained inert bytes. No filesystem lookup occurs.

Logical names and roots are case-sensitive relative slash-separated strings of
at most 1,024 UTF-8 bytes. Empty segments, `.`/`..`, leading or trailing slash,
backslash, colon anywhere and Unicode control characters reject. No path or
Unicode normalization occurs. Supplied file names must be unique. Media types
are required nonblank ASCII strings without controls, at most 1,024 bytes, and
are retained without trimming or inference. File payloads are unrestricted bytes;
archive content may be retained but is never expanded or treated as packaging.

`COMPLETE` and `PARTIAL` are the only coverage values. The validator retains the
supplier's declaration; it does not verify external completeness, authorization,
native validity or snapshot acceptance.

## Intake bounds

| Input | Inclusive ceiling |
| --- | --- |
| Original inventory bytes | 4 MiB |
| Supplied files | 256 |
| Each file payload | 4 MiB |
| Inventory plus file payload bytes | 32 MiB |
| Resources | 1,000 |
| Relation occurrences | 10,000 |
| Each partition list | 1,000 |
| JSON container depth, root container counted as 1 | 32 |

A MiB is 1,048,576 bytes. JSON depth, duplicate keys and collection ceilings
are checked before typed collection deserialization. Transport metadata is
bounded separately by the logical-name and media-type limits. Source run,
retention and publication budgets belong to the proposed control plane.

## Rust boundary and digests

`source_bundle::validate_bundle(&[u8], &[SuppliedFile])` returns an immutable,
owned `ValidatedBundle` or a sanitized `BundleError`. A `SuppliedFile` borrows
`logical_name`, `media_type` and `bytes`; validation retains independent copies.
No disk, network, compilation or native model operations occur.

The result exposes `inventory_bytes()`, typed `inventory()`, `files()`,
`inventory_digest()` and `bundle_digest()`. Files are returned sorted by exact
logical-name UTF-8 bytes; resource and relation arrays retain authored order.
Each retained file exposes its original bytes, typed name/media type and digest.
Digest values expose `purpose()`, `bytes()` and lowercase `hex()`; inventory,
bundle and raw file-content purposes are distinct. Their encoding is defined
by the [digest contract](source-integration-contracts.md#supplied-byte-digest-encoding).

Errors retain fixed categories without raw pointers, unknown keys, input content
or serializer diagnostics. `JsonDepth` identifies excessive nesting; `Inventory`
covers malformed JSON and field shape. Other categories distinguish limits,
text, locators, media types, profile, duplicates, partition and unavailable
supplied owners/files. These categories do not establish native resolution.

Public [boundary tests](../../rsworkspace/crates/trogon-atlas-core/tests/source_bundle.rs)
and [fixed digest vectors](../../rsworkspace/crates/trogon-atlas-core/tests/source_bundle_vectors.rs)
cover the implemented intake slice. They do not prove source persistence or
reconciliation acceptance.
7 changes: 5 additions & 2 deletions docs/reference/source-integration-acceptance.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,11 @@ Status: proposed acceptance requirements for the
records and source run operations are not implemented by this document. Linked
native fixtures provide existing anchors and examples of native behavior;
they do not prove source registration, snapshot retention, reconciliation,
coordinated publication, cancellation or fidelity reporting. Every source case
below requires future executable evidence.
coordinated publication, cancellation or fidelity reporting. The [supplied bundle profile](source-bundle-profile.md) has executable core
[boundary tests](../../rsworkspace/crates/trogon-atlas-core/tests/source_bundle.rs)
and [digest vectors](../../rsworkspace/crates/trogon-atlas-core/tests/source_bundle_vectors.rs).
They cover intake only. Source retention, native mapping and run cases below
require future executable evidence.

## Connected fixture inputs

Expand Down
17 changes: 10 additions & 7 deletions docs/reference/source-integration-contracts.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Source integration contracts

Status: proposed, native-first design. Source registration, retained snapshots,
Status: source control design proposed; the [supplied bundle profile](source-bundle-profile.md)
and its Rust core validator are implemented. Source registration, retained snapshots,
overlays, reconciliation runs and their persistence are not implemented by this
reference. Channel/DataStore, Specification/API, DataProduct, Team/Person and
Decision/Document are implemented native foundations. Their contracts remain
Expand Down Expand Up @@ -81,13 +82,14 @@ encoding below, independently of native content normalization.

### Supplied-byte digest encoding

The proposed `supplied-native-v1` profile accepts an inventory document and a
finite set of named files; it does not accept archives. The inventory is exact
The implemented `supplied-native-v1` intake profile accepts an inventory document
and a finite set of named files; it does not unpack archive containers. The inventory is exact
UTF-8 JSON bytes describing the registration, opaque source version, input
profile revision, partition/coverage, resource keys, ordered relation occurrences
and pointers. Repeated object keys, invalid JSON and invalid UTF-8 reject before
acceptance. Its eventual typed wire schema must represent those fields without
an arbitrary-property escape hatch. Whitespace and object-key order are retained
intake. Its typed JSON shape is defined in the
[profile reference](source-bundle-profile.md#inventory-json), without an
arbitrary-property escape hatch. Whitespace and object-key order are retained
input bytes, so changing either changes source identity even if native content
would compare equal.

Expand All @@ -114,10 +116,11 @@ against the profile's limits.

Logical names are unique, case-sensitive, relative slash-separated names, at
most 1,024 UTF-8 bytes. Empty segments, `.`/`..`, leading/trailing slash,
backslash, control characters, URI schemes and drive prefixes reject; no path
backslash, colon anywhere, control characters, URI schemes and drive prefixes
reject; no path
or Unicode normalization is performed. Neither logical names nor media types
are trimmed or inferred. A media type is required nonblank ASCII without control
characters. Duplicate logical names reject rather than overwrite. File-list
characters, at most 1,024 bytes. Duplicate logical names reject rather than overwrite. File-list
transport order does not affect the digest; authored inventory relation/list
order does. Changing version, scope or coverage must change the inventory bytes
and therefore its digest. Transport timestamps, current native resolutions and
Expand Down
5 changes: 3 additions & 2 deletions rsworkspace/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions rsworkspace/crates/trogon-atlas-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ prost = { workspace = true }
prost-types = { workspace = true }
prost-reflect = { version = "0.16", features = ["serde"] }
serde_json = { workspace = true }
serde = { workspace = true }
sha2 = { workspace = true }
thiserror = { workspace = true }
url = "2.5"
Expand Down
1 change: 1 addition & 0 deletions rsworkspace/crates/trogon-atlas-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ pub mod responsibility;
mod responsibility_refs;
pub mod schema;
pub mod semantic_eq;
pub mod source_bundle;
pub mod specification;
mod specification_refs;
pub mod system_meta;
Expand Down
Loading
Loading