@phosphorco/bb-identity 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/EDITING.md +131 -0
- package/NATIVE-SOURCES.md +222 -0
- package/README.md +18 -0
- package/dist/bb-entry-runtime.js +107 -87
- package/dist/client-entry-runtime.js +128 -36
- package/dist/editing-runtime.js +1845 -0
- package/dist/host-runtime.js +54 -29
- package/dist/index-runtime.js +21 -0
- package/dist/model-runtime.js +21 -0
- package/dist/native-runtime.js +476 -0
- package/dist/native-testing-runtime.js +11 -0
- package/dist/react-entry-runtime.js +253 -51
- package/dist/state-controller-runtime.js +96 -11
- package/dist/state-runtime.js +95 -11
- package/dist/testing-runtime.js +112 -92
- package/editing.d.ts +137 -0
- package/host.d.ts +1 -0
- package/native-testing.d.ts +15 -0
- package/native.d.ts +100 -0
- package/package.json +20 -3
- package/react.d.ts +16 -0
package/EDITING.md
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
# Opt-in shared work-product editing
|
|
2
|
+
|
|
3
|
+
`@phosphorco/bb-identity/editing` uses the production state controller and binding
|
|
4
|
+
lifetime with an explicit `bb-identity.editing/v1` protocol. Legacy `/state`
|
|
5
|
+
consumers retain their existing outcomes, codecs, auto-dispatch and blocked edit
|
|
6
|
+
behavior. This entry adds no mandatory SDK or React runtime dependency.
|
|
7
|
+
|
|
8
|
+
| Feature owns | Package owns | UI owns |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| Shared storage, document targets and schema | Session and controller lifetime fences | Text controls and conflict choices |
|
|
11
|
+
| Atomic admission, immutable request receipts and retention | Desired generation, exact flight, acknowledged base | Explicit publication and checkpoint/export actions |
|
|
12
|
+
| Protocol advertisement and selected v1 transport | Versioned codecs and receipt/request validation | Separate publication and backup presentation |
|
|
13
|
+
| Real map epoch, monotone admission ordinal, opaque revision | Bounded reconnect and recovery | Feature diagnostics and labels |
|
|
14
|
+
| Draft adapter and conditional checkpoint revisions | Shared Provider retirement coordination | Explicit recovery candidate selection |
|
|
15
|
+
|
|
16
|
+
A shared map has no personal owner. `draftAddress.owner` is the actual actor
|
|
17
|
+
whose editing work is retained. `target` selects the shared feature document.
|
|
18
|
+
Do not send this editing scope to legacy personal-state server routes or
|
|
19
|
+
register a fake personal state owner for the shared document. The feature
|
|
20
|
+
adapter loads shared content into an actor's editing scope and supplies real
|
|
21
|
+
version metadata. Epoch changes on reset/recreation; sequence increases inside
|
|
22
|
+
the admission transaction. Keep opaque revision identity in the feature value
|
|
23
|
+
when the feature command needs it. Do not derive sequence from time, UUID or hash.
|
|
24
|
+
|
|
25
|
+
## Controller and binding
|
|
26
|
+
|
|
27
|
+
Construct `createIdentityEditingState({draftAddress,target,targetCodec,expected,
|
|
28
|
+
ownerSession,definition,transport,drafts?,scheduler?,onConflict,initializeEmpty,
|
|
29
|
+
currentSession})`. `currentSession` observes the live client, never a captured
|
|
30
|
+
initial session. The transport must be explicitly negotiated with the feature's
|
|
31
|
+
v1 endpoint before construction; the protocol literal and a successful local
|
|
32
|
+
codec do not prove remote capability or durable storage.
|
|
33
|
+
|
|
34
|
+
Prefer `useIdentityEditingBinding({resourceKey,target,targetCodec,create,
|
|
35
|
+
onUnpersistedDraft?})` and `useIdentityEditingSnapshot(binding)` from `/react`
|
|
36
|
+
under the continuously mounted `BbIdentity.Provider` and `BbIdentity.Context`.
|
|
37
|
+
`create({session,subject,ownerSession})` returns the controller; `subject` is the
|
|
38
|
+
actual actor. The hook acquires resources only after commit. Use a stable
|
|
39
|
+
`resourceKey` describing the feature/schema/draft record. Semantic encoded
|
|
40
|
+
Target changes replace the owner; object and callback recreation alone do not.
|
|
41
|
+
Callback changes are visible only after commit. A manually owned resource may
|
|
42
|
+
use `bindIdentityEditingState({...options,client,view})` from `/editing`.
|
|
43
|
+
|
|
44
|
+
The shared binding fences delayed recovery/conflict/checkpoint commands with
|
|
45
|
+
`currentOwnerSession()` before and after awaits. A1 → B2 → A3 creates distinct
|
|
46
|
+
controller incarnations even when actor A returns. A detached controller cannot
|
|
47
|
+
be revived; new work requires a new controller and explicit recovery. The
|
|
48
|
+
controller's borrowed `draftStorage` identity lets the Provider wait for an old
|
|
49
|
+
write before enumerating replacement recovery candidates. The Provider never
|
|
50
|
+
owns or disposes feature storage.
|
|
51
|
+
|
|
52
|
+
## Publication and backup are separate
|
|
53
|
+
|
|
54
|
+
`edit(B)` changes desired value and generation. Loaded active same-owner drafts
|
|
55
|
+
remain editable through conflict, unknown save, definitive rejection and failed
|
|
56
|
+
checkpoint. Session/owner change, detach/dispose, migration and load failure
|
|
57
|
+
fence editing. An authoritative successful reload can resolve a load failure;
|
|
58
|
+
returning to an old identity cannot revive a retired controller.
|
|
59
|
+
|
|
60
|
+
Edits never publish automatically. `flush()` captures an immutable request
|
|
61
|
+
before the first checkpoint or transport await. With pending A, one explicit
|
|
62
|
+
flush reconciles A only. It never follows reconciliation by sending newer B.
|
|
63
|
+
A successful `Result<void>` can mean A was acknowledged while B remains dirty;
|
|
64
|
+
always render the snapshot's desired/acknowledged/publication/backup facets.
|
|
65
|
+
A rejected receipt returns a failed Result, retires A without changing base,
|
|
66
|
+
and retains B plus structured diagnostics. After correction, a later explicit
|
|
67
|
+
flush submits a new operation. Retrying a checkpoint or reading unchanged data
|
|
68
|
+
cannot resolve rejection or an unknown save. Conflict is also a failed explicit
|
|
69
|
+
publication; decisions capture a token that changes immediately when typing B.
|
|
70
|
+
|
|
71
|
+
`checkpoint()` serializes desired B, acknowledged base, exact pending A and
|
|
72
|
+
last definitive rejection. `snapshot.draft` remains exportable when it fails.
|
|
73
|
+
`checkpoint.status` is disabled, local-only, writing, backed-up or failed;
|
|
74
|
+
`generation` and `revision` identify the last committed checkpoint. A generation
|
|
75
|
+
alone cannot prove backup: receipt/pending/base/rejection metadata must also
|
|
76
|
+
match. Without DraftStorage there is no browser-death recovery guarantee.
|
|
77
|
+
|
|
78
|
+
On retirement failure, `useIdentityEditingPreservationFailures()` retains the
|
|
79
|
+
full EditingDraft, including Target, without a fresh identity RPC. Its bounded
|
|
80
|
+
Provider presentation records have exact generation tokens.
|
|
81
|
+
`useAcknowledgeIdentityEditingPreservationFailure()(generation)` only dismisses
|
|
82
|
+
that record; it neither retries storage nor proves backup or publication.
|
|
83
|
+
|
|
84
|
+
## Exact request finality and recovery
|
|
85
|
+
|
|
86
|
+
An `EditingRequest` binds protocol, Target and the full immutable StateMutation,
|
|
87
|
+
including actual actor/session, ownerSession, expected version, local generation,
|
|
88
|
+
schema, operation ID and submitted value. Every final receipt echoes this exact
|
|
89
|
+
request. The feature must reserve/check its canonical request fingerprint before
|
|
90
|
+
CAS and atomically retain the original outcome, including rejected diagnostics.
|
|
91
|
+
Changed payload with the same ID is invalid-operation. The package validates the
|
|
92
|
+
full echoed request; matching operation ID alone cannot authorize retirement.
|
|
93
|
+
Bounds are exported as `EDITING_LIMITS`; codecs reject malformed versions,
|
|
94
|
+
diagnostics, recovery data and mismatched resource metadata.
|
|
95
|
+
|
|
96
|
+
`reconcile(originalRequest)` uses the current authenticated invocation to inspect
|
|
97
|
+
the original request, even when its actor's server session has since changed.
|
|
98
|
+
Never rewrite the original request's expected session or ownerSession. A final
|
|
99
|
+
saved outcome contains the admitted A snapshot, even if remote current is C.
|
|
100
|
+
Load C afterwards and review divergence against A's acknowledged base. A final
|
|
101
|
+
conflict likewise carries the original captured remote snapshot. Pending,
|
|
102
|
+
unknown, expired and ordinary transport errors retain A. Even absent-final does
|
|
103
|
+
not cause automatic or implicit replay in this manual v1 controller. No new
|
|
104
|
+
operation is created while A is unresolved.
|
|
105
|
+
|
|
106
|
+
Draft discovery is bounded to 20 candidates by full actor/draft address/Target.
|
|
107
|
+
Selection is explicit; codecs preserve B and A independently across controller
|
|
108
|
+
sessions. `remove({target,draftKey},revision)` must conditionally delete only that
|
|
109
|
+
exact checkpoint. A newer checkpoint cannot be erased by stale recovery UI.
|
|
110
|
+
|
|
111
|
+
Source/controller/binding tests and local packed-consumer tests establish only
|
|
112
|
+
the exercised source/artifact contracts. Actual feature negotiation, durable
|
|
113
|
+
atomic receipt storage, registry adoption and live runtime coverage require
|
|
114
|
+
separate evidence.
|
|
115
|
+
|
|
116
|
+
Protocol metadata is validated through typed normalization too: encoders retain
|
|
117
|
+
supplied protocol fields so an unsupported outer or nested version cannot be
|
|
118
|
+
rewritten into v1. Recovered rejection evidence must match the draft's schema
|
|
119
|
+
and cannot come from a future local generation or the same still-pending
|
|
120
|
+
operation. Historical actor session and ownerSession remain unchanged; a new
|
|
121
|
+
active session may recover and reconcile that exact historical request.
|
|
122
|
+
|
|
123
|
+
Use `editingCodecs(valueCodec,targetCodec).scope` at the feature's v1 load and
|
|
124
|
+
subscription wire boundary. It encodes/decodes the actual `EditingScope`:
|
|
125
|
+
`{draftAddress,schemaVersion,target,expected}`. Public ID and identity codecs
|
|
126
|
+
validate the draft owner and exact opaque session; draft owner must equal the
|
|
127
|
+
expected actual actor, while Target remains feature data. The codec rejects
|
|
128
|
+
unknown input keys and unsafe schema integers, preserves typed Target wire
|
|
129
|
+
conversion, and shares `EDITING_LIMITS.bytes`. A load scope contains no invented
|
|
130
|
+
operation, revision, submitted value or mutation. Protocol negotiation still
|
|
131
|
+
belongs to the selected v1 endpoint and transport.
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Native source evidence — 0.4.0 candidate
|
|
2
|
+
|
|
3
|
+
`@phosphorco/bb-identity/native` normalizes bounded, retained public SDK
|
|
4
|
+
snapshots into `NativeSourceEvidence`. It preserves native source facts without
|
|
5
|
+
manufacturing a Contribution, successful history lookup, attempt, person, or
|
|
6
|
+
agent identity. Existing Contribution/ExecutionProvenance APIs are unchanged.
|
|
7
|
+
|
|
8
|
+
| Caller owns | Package owns | Host/public SDK owns |
|
|
9
|
+
| --- | --- | --- |
|
|
10
|
+
| Reading and freezing snapshots; retention/rewrite fences | Bounds and validation | Retained events and visible timeline projection |
|
|
11
|
+
| Cursors, discovery, budgets, persistence and wake/recovery | Exact request/turn and projection/item joins | Native attribution fields when recorded |
|
|
12
|
+
| Product text selection and semantic support | Independent evidence coverage | Genuine Contribution/ExecutionProvenance history |
|
|
13
|
+
| Rendering and product acceptance | Optional bounded history read composition | Native producer semantics |
|
|
14
|
+
|
|
15
|
+
No registry, RPC, timers, scanner, subscription, storage, or background owner is
|
|
16
|
+
introduced. This is request-scoped normalization; the caller owns any durable
|
|
17
|
+
work resumed after restart. A wake is never source evidence.
|
|
18
|
+
|
|
19
|
+
## Public API
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import { createNativeSourceAdapter } from '@phosphorco/bb-identity/native';
|
|
23
|
+
|
|
24
|
+
const adapter = createNativeSourceAdapter({ history: binding.server.history });
|
|
25
|
+
// These are actual public SDK return values captured by the caller's history reader.
|
|
26
|
+
const events = await bb.sdk.threads.events.list({ threadId, order: 'asc', limit: '200' });
|
|
27
|
+
const timeline = await bb.sdk.threads.timeline({
|
|
28
|
+
threadId, includeNestedRows: 'true', deferContent: 'false',
|
|
29
|
+
summaryOnly: 'false', segmentLimit: '200',
|
|
30
|
+
});
|
|
31
|
+
// The caller must freeze/fence matching retained snapshots before admission.
|
|
32
|
+
const result = adapter.resolve({
|
|
33
|
+
source: {
|
|
34
|
+
kind: 'assistant-terminal', threadId, terminalEventId,
|
|
35
|
+
scope: { turnId },
|
|
36
|
+
},
|
|
37
|
+
events, timeline,
|
|
38
|
+
});
|
|
39
|
+
if (result.ok) {
|
|
40
|
+
const nativeEvidence = result.value;
|
|
41
|
+
// Optional: actual existing history reads, retaining their exact outcomes.
|
|
42
|
+
const enriched = await adapter.enrich(nativeEvidence, { signal });
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
The example targets the inspected fork SDK
|
|
47
|
+
`0.6.52+phosphor.975e38f02f1a.sdk.12eb78c20820`. Timeline flags such as
|
|
48
|
+
`deferContent` are host-specific; the public registry SDK 0.6.31 does not
|
|
49
|
+
declare that flag. Its baseline witness calls `threads.timeline({threadId})`
|
|
50
|
+
using its own public contract. Do not add undeclared flags to a consumer.
|
|
51
|
+
The example illustrates public calls, not an atomic snapshot transaction.
|
|
52
|
+
Concurrent rewrites, history pagination, and changed projection snapshots need a
|
|
53
|
+
caller-owned fence. The adapter cannot authenticate the origin or revision of
|
|
54
|
+
injected snapshots. Do not combine an old event page and a new timeline page and
|
|
55
|
+
claim they describe one frozen retained history.
|
|
56
|
+
|
|
57
|
+
References are opaque native IDs:
|
|
58
|
+
|
|
59
|
+
- `request-group`: threadId, eventId, requestId, groupIndex (zero based).
|
|
60
|
+
- `event`: threadId, eventId; currently normalizes `client/turn/requested`.
|
|
61
|
+
Multiple groups require an explicit `request-group`; other event types yield
|
|
62
|
+
unsupported source coverage.
|
|
63
|
+
- `assistant-item`: threadId, itemId, terminalEventId, scope.turnId.
|
|
64
|
+
- `assistant-terminal`: threadId, terminalEventId, scope.turnId.
|
|
65
|
+
|
|
66
|
+
Terminal references contain no attemptId. A terminal event must be
|
|
67
|
+
`turn/completed` with the exact scope.turnId. Its status remains completed,
|
|
68
|
+
failed, or interrupted. Two terminals in one turn remain distinct sources.
|
|
69
|
+
An attempt ID appears only inside an actual optional history response.
|
|
70
|
+
|
|
71
|
+
## Source and identity semantics
|
|
72
|
+
|
|
73
|
+
A request group uses its exact `inputGroups[groupIndex]`, falling back to the
|
|
74
|
+
single native input only when groups were not recorded. Authors and editors
|
|
75
|
+
are accepted only from group-aligned native arrays. Missing/misaligned arrays
|
|
76
|
+
are explicit unknown coverage; the adapter never borrows another group's author.
|
|
77
|
+
Text includes visible text parts in order, separated by newlines. Non-text
|
|
78
|
+
attachments are not expanded, and agent-only text is excluded with an explicit
|
|
79
|
+
coverage reason. Request-wide native mentioned targets retain their structured
|
|
80
|
+
provider source and are never converted to per-group authorship.
|
|
81
|
+
|
|
82
|
+
`origin` preserves native dispatch initiator user/agent/system. `user` means the
|
|
83
|
+
native initiator value; it does not assert a person. Native structured author,
|
|
84
|
+
latest editor, mentions, and dispatch senderThreadId are independent. A machine
|
|
85
|
+
author can accompany a user initiator. No text envelope, participant roster,
|
|
86
|
+
first/latest author, display name, or parent thread supplies missing identity.
|
|
87
|
+
|
|
88
|
+
Assistant output has origin assistant, author/editor null, and no inherited
|
|
89
|
+
mentions. Its accepted inputs identify execution causes, never output authors.
|
|
90
|
+
`turn/input/accepted.data.clientRequestId` must join exactly one preceding
|
|
91
|
+
request event to the accepted event's scope.turnId. For a selected request
|
|
92
|
+
source, that exact event must be the unique preceding candidate; a later event
|
|
93
|
+
reusing its request ID cannot inherit an earlier event's acceptance. Many requests and groups
|
|
94
|
+
can share a turn. Supplied windows cannot prove all input causes were retained,
|
|
95
|
+
so execution coverage remains partial even when every included join succeeds.
|
|
96
|
+
|
|
97
|
+
The native source contract does not establish initiating person, carried person,
|
|
98
|
+
agentId, or personal delegation. Those fields remain explicitly unknown/null.
|
|
99
|
+
Optional genuine history may contain an integration assertion or execution
|
|
100
|
+
correlation; that assertion retains its original basis and does not silently
|
|
101
|
+
populate stronger native lineage fields.
|
|
102
|
+
|
|
103
|
+
## Recorded external people
|
|
104
|
+
|
|
105
|
+
`NativeEvent`, `NativeActor` and `NativeMention` retain their actual public SDK
|
|
106
|
+
meanings. `NativeSourceActor = NativeActor | ExternalPersonSnapshotV1` is a
|
|
107
|
+
separate package-owned recorded-source capability. `NativeSourceEvent` derives
|
|
108
|
+
all event fields from the SDK and overlays only the request's optional,
|
|
109
|
+
group-parallel `p6rAuthors`/`p6rEditors` arrays with that actor type. Ordinary SDK
|
|
110
|
+
event arrays remain assignable to `NativeSourceSnapshot.events`.
|
|
111
|
+
|
|
112
|
+
The adapter validates recorded external people through the existing public
|
|
113
|
+
`externalPersonSnapshotCodec`. It preserves `evidence: 'integration-asserted'`,
|
|
114
|
+
identity and presentation; it never promotes that evidence to provider-verified.
|
|
115
|
+
Author and latest editor remain independently indexed by group. Invalid asserted
|
|
116
|
+
people return invalid-input; missing or misaligned arrays remain unknown.
|
|
117
|
+
|
|
118
|
+
For typed recorded input, decode the actor with that codec and use the successful
|
|
119
|
+
value in an event satisfying `NativeSourceEvent`. This explicit source input is
|
|
120
|
+
not an augmentation of the SDK. The inspected fork's host source admits such
|
|
121
|
+
assertions, while its consumed SDK version still excludes them; assigning the
|
|
122
|
+
richer event to that stale `NativeEvent` is a type error. Public SDK 0.6.31 lacks
|
|
123
|
+
the attribution properties entirely. The package seam does not establish that
|
|
124
|
+
any baseline or live producer records them. Actual producer and adopter evidence
|
|
125
|
+
remain separate gates. Assistant authorship and personal lineage remain unchanged.
|
|
126
|
+
|
|
127
|
+
## Retained terminal output join
|
|
128
|
+
|
|
129
|
+
The adapter uses the supported public `threads.timeline` projection. It does
|
|
130
|
+
not reconstruct visible text by concatenating transient deltas, nor select only
|
|
131
|
+
completed items. It accepts assistant conversation rows with the exact native
|
|
132
|
+
thread and turn and a source range wholly through the selected terminal.
|
|
133
|
+
Both range endpoints must join supplied text-bearing agentMessage delta or
|
|
134
|
+
completed agentMessage events with the same native item ID, recorded parentToolCallId,
|
|
135
|
+
and turn. IDs, nonempty endpoint text and optional commentary/final_answer phase
|
|
136
|
+
are validated before use. Omitted/nonstring request text and invalid visibility
|
|
137
|
+
are rejected rather than coerced. Missing/invalid row IDs withhold those rows.
|
|
138
|
+
Every returned text row preserves its recorded parentToolCallId; null means the
|
|
139
|
+
public field was absent, not recovered root delegation. An assistant-item selector
|
|
140
|
+
matching several recorded parent instances is ambiguous and supplies no text. The
|
|
141
|
+
projection's row ID is retained, never parsed for hidden identity. Per-text
|
|
142
|
+
source IDs, sequence range, item ID, and available completed-item phase survive.
|
|
143
|
+
Deltas without recorded phase keep phase null.
|
|
144
|
+
|
|
145
|
+
This permits retained visible commentary and final output, including text flushed
|
|
146
|
+
at failed/interrupted terminals without item/completed. Public timeline text is
|
|
147
|
+
the authority; the adapter does not invent projection behavior. Empty text and
|
|
148
|
+
non-assistant/tool rows contribute no text. Cross-terminal ranges, missing
|
|
149
|
+
endpoints, or different item IDs cannot supply text. Plan/reasoning rows are not
|
|
150
|
+
accepted as agentMessage output. Missing/deferred nested rows and incomplete
|
|
151
|
+
pages disclose coverage gaps. A bounded empty page never proves a turn had no
|
|
152
|
+
retained assistant text. The caller decides whether retained text is substantive.
|
|
153
|
+
|
|
154
|
+
Sequence endpoints prove the structural join within supplied matching snapshots.
|
|
155
|
+
They do not prove producer stability, identical revisions across independent
|
|
156
|
+
reads, or that this package observed a real interrupted producer.
|
|
157
|
+
|
|
158
|
+
## Independent coverage and optional history
|
|
159
|
+
|
|
160
|
+
`coverage.source` describes admitted text and the selected source within the
|
|
161
|
+
snapshot. It is separate from attribution, execution and personalLineage.
|
|
162
|
+
`known` source coverage does not imply complete thread traversal or identity.
|
|
163
|
+
Native facts do not change `binding.server.history` outcomes.
|
|
164
|
+
|
|
165
|
+
`enrich` optionally calls the existing history reader using native-event queries
|
|
166
|
+
for request sources or assistant input requests. It retains each exact Result,
|
|
167
|
+
including pending, unavailable, errors, partial pages and continuation cursors.
|
|
168
|
+
Attempts are queried only via genuinely returned same-thread Contribution refs.
|
|
169
|
+
Responses stay under `history` with their query basis; they are not relabeled as
|
|
170
|
+
source authors or resolved assistant executions. In particular, a returned
|
|
171
|
+
attempt with a different correlation turn is not an execution of this assistant
|
|
172
|
+
source. Consumers must match genuine correlation.threadId/turnId and contribution
|
|
173
|
+
causes before using optional attempts. No pages are silently followed, unknown
|
|
174
|
+
results retried, or history coverage upgraded. Existing readers may throw
|
|
175
|
+
programmer errors according to the existing Result contract.
|
|
176
|
+
|
|
177
|
+
`NATIVE_SOURCE_LIMITS` publishes 2000 events, 2000 nested projection rows, 2 MiB
|
|
178
|
+
UTF-8 serialized input, 8 nested levels, 16 total enrichment calls and 256-character
|
|
179
|
+
native identifiers, plus 64 levels for the complete plain-data representation.
|
|
180
|
+
A bounded stable copy reads own data descriptors, including non-enumerable data,
|
|
181
|
+
and rejects accessors, callable serialization hooks, cycles and exotic prototypes.
|
|
182
|
+
It bounds consumed UTF-8 data with structural overhead, then the UTF-8 JSON
|
|
183
|
+
serialization of that same copied representation (including escape expansion).
|
|
184
|
+
Normalization consumes only the checked copy; no original getters/toJSON run.
|
|
185
|
+
Oversized/malformed input returns invalid-input. Reads are
|
|
186
|
+
cancellable between operations and use the reader's supplied cancellation
|
|
187
|
+
semantics. No feature work is launched after return.
|
|
188
|
+
|
|
189
|
+
## Compatibility and proof
|
|
190
|
+
|
|
191
|
+
The new entry imports SDK types only; its emitted runtime imports no SDK or
|
|
192
|
+
React. Existing root, model, client, server and other exports/peer ranges retain
|
|
193
|
+
their previous contract. The current declaration witness uses installed SDK
|
|
194
|
+
`0.6.52+phosphor.975e38f02f1a.sdk.12eb78c20820`, including optional native
|
|
195
|
+
p6rAuthors/p6rEditors/p6rMentionedTargets. NativeActor and NativeMention derive
|
|
196
|
+
conditionally from the SDK's public optional properties; when absent (as in public
|
|
197
|
+
SDK 0.6.31), their member types are never. Snapshots without recorded attribution
|
|
198
|
+
retain null authors/editors and empty mentions; user dispatch never supplies a person.
|
|
199
|
+
No fork property or protocol is copied to emulate a missing capability. Public
|
|
200
|
+
0.6.31 all-entry declarations and its minimal native calls are a separate actual-peer
|
|
201
|
+
conformance job, without skipLibCheck; missing upstream declaration dependencies
|
|
202
|
+
are resolved by that fixture separately. Existing peers and default exports
|
|
203
|
+
remain unchanged. Older hosts can keep existing entries;
|
|
204
|
+
using `/native` requires the public snapshot types/capabilities exercised by the
|
|
205
|
+
adopter. Missing optional attribution on a host stays unknown.
|
|
206
|
+
|
|
207
|
+
`@phosphorco/bb-identity/native/testing` exports
|
|
208
|
+
`defineNativeSourceConformance({test, resolve, cases})`. Pass the adopter's actual
|
|
209
|
+
source path and independently authored semantic oracles. The kit refuses empty
|
|
210
|
+
case lists; it does not substitute a fake adapter or assert live coverage.
|
|
211
|
+
|
|
212
|
+
Package source fixtures cover human/machine/agent dispatch, author/editor/mention
|
|
213
|
+
separation, multiple requests/groups sharing a turn, commentary/final and
|
|
214
|
+
failed/interrupted delta projections, exact joins and refusals, missing lineage,
|
|
215
|
+
bounds, and actual optional reader outcomes. These are synthetic SDK and recorded-source snapshots, including codec-validated
|
|
216
|
+
external assertions; none establishes a live producer fact.
|
|
217
|
+
Public declarations, emitted entries and a scratch packed consumer are separate
|
|
218
|
+
package proofs. Registry publication, exact-version consumer adoption,
|
|
219
|
+
producer/live fixtures, rewrite/outage/restart and host acceptance remain
|
|
220
|
+
separate gates. Source version 0.4.0 is a candidate; installed org consumers on
|
|
221
|
+
0.3.1 do not gain this API until a separately authorized registry release and
|
|
222
|
+
exact-version adoption.
|
package/README.md
CHANGED
|
@@ -106,6 +106,20 @@ Notifications as a third consumer. Offline fixtures establish specific safety
|
|
|
106
106
|
properties but do not replace those migrations or the master plan's
|
|
107
107
|
upstream → fork → upstream → fork authored-session compatibility proof.
|
|
108
108
|
|
|
109
|
+
## Native source evidence (0.4.0 candidate)
|
|
110
|
+
|
|
111
|
+
The additive `/native` entry normalizes retained public SDK event/group/item/terminal
|
|
112
|
+
snapshots into evidence distinct from Contribution history. It preserves independent
|
|
113
|
+
source, attribution, execution and lineage coverage. See [NATIVE-SOURCES.md](NATIVE-SOURCES.md)
|
|
114
|
+
for API, ownership, public joins, bounds and proof limits; `/native/testing` supplies
|
|
115
|
+
the caller-driven semantic conformance kit. This source candidate is not evidence
|
|
116
|
+
of registry publication or installed consumer adoption.
|
|
117
|
+
|
|
118
|
+
The combined 0.4.0 source candidate also adds opt-in `/editing` and explicit React
|
|
119
|
+
hooks for continued local typing across unknown publication, conflicts and backup
|
|
120
|
+
failures. See [EDITING.md](EDITING.md) for the independent editing/v1 contract and
|
|
121
|
+
proof limits; existing state protocol and default behavior remain unchanged.
|
|
122
|
+
|
|
109
123
|
## Entry points
|
|
110
124
|
|
|
111
125
|
| Import suffix | Runtime/declaration status | Responsibility |
|
|
@@ -477,3 +491,7 @@ V1 receipts confirm the frozen `externalContribution`. Reconcile V1 exclusively
|
|
|
477
491
|
The default host rendering policy adds the integration sender envelope once. A producer such as Rosetta must select `externalMessageRendering: 'producer'` at binding construction; its prompt bytes remain unchanged. A capable native host projects the person into the native timeline while contribution/attempt history keeps the external origin and optional `personAttribution`. This does not add native-message history queries.
|
|
478
492
|
|
|
479
493
|
Native history containing integration-asserted person authors requires a capable runtime even after queues drain or plugins are downgraded. Do not roll back to a host that only accepts provider-verified person authors. Package-only rollback retains the legacy external path; it does not make old native readers understand newer stored authorship.
|
|
494
|
+
|
|
495
|
+
### 0.3.1 decoder corrections
|
|
496
|
+
|
|
497
|
+
V1 external subjects are opaque nonempty strings of at most256 characters, including email-shaped or percent-encoded subjects. They are not BB resource IDs. Contribution and attempt-history output normalize additive person snapshot, identity, and presentation fields while preserving strict V1 input decoding. `externalContributionOutcomeV1Codec` from `/host` validates and normalizes persisted V1 outcomes; consumers must additionally compare submitted receipts with the reserved operation ID and frozen contribution. A stored final lacking that evidence remains uncertainty and must not trigger a resend.
|