@phosphorco/bb-cross-references 0.0.0-stage → 0.1.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/CONTRACT.md ADDED
@@ -0,0 +1,109 @@
1
+ # Cross References, package 0.1.0 / wire v1
2
+
3
+ | Feature owns | Contract package owns | Rendering consumer owns |
4
+ | --- | --- | --- |
5
+ | Storage, migrations, keys and durable delivery | Resource DTOs, Zod bounds and canonicalization | Explicit target SDK injection and refresh schedule |
6
+ | CAS, revisions, outbox and write recovery | Fixed central RPC schemas and bounded client | Controls, layout, local policy and presentation |
7
+ | Permitted references and maximum count | Thread/URL normalization and conformance kit | Error presentation and optional dependency behavior |
8
+
9
+ This package makes Cross References v1 reusable across independently installed
10
+ plugins. It has no database, registry, lifecycle, authorization, singleton,
11
+ SDK slot hooks, retry loop or implicit write destination. Feature attachment DTOs and
12
+ storage remain feature-owned.
13
+
14
+ ## Entries
15
+
16
+ Root exports existing central canonical functions/constants, resource and
17
+ projection DTOs, `normalizeProjectionCommand`, and the named v1 Zod schemas.
18
+ Root depends only on Zod and browser-safe `@noble/hashes`; SHA-256 is synchronous.
19
+ `/bb` exports `createCrossReferencesClient(sdk, targetPluginId =
20
+ "cross-references", options?)` using public server/browser SDK type imports.
21
+ `/react` provides shared controls with injected APIs; `/styles.css` their styles.
22
+ Data crosses plugin boundaries; React components never do.
23
+
24
+ `LinkedReferences` requires `ownerKey`, an explicit stable logical storage owner,
25
+ plus injected get/replace/search/thread callbacks and native navigation. Changing
26
+ ownerKey remounts its whole read/mutation/picker lifetime; late results from the
27
+ old owner are dropped. Callback objects may change without changing that logical
28
+ owner. Consumers adapt their local snapshots; the component does not call slot
29
+ hooks or central RPC. Refresh uses mount, reconnect, a changed refreshToken or the
30
+ explicit button, with no idle polling.
31
+
32
+ `/testing` exports `runCrossReferencesConformance({sdk, pluginId?, command})`.
33
+ Use an isolated active source with a nonempty target list and the adopter's
34
+ actual registered handlers. The helper drives describe, apply, duplicate
35
+ mutation, get round-trip and backlinks through the production client. It
36
+ reports source conformance, not host loading or live composition.
37
+
38
+ ## Identity and digests
39
+
40
+ Identity is `{provider,keys}`; presentation never changes identity. Key names
41
+ are lexically sorted and values NFC-normalized. Identity JSON keeps exact
42
+ `{provider,keys}` property order. SHA-256 is lower-case hex over UTF-8 JSON.
43
+ Projection JSON keeps `{protocolVersion,producerPluginId,source,tombstone,targets}`
44
+ order; target order and presentation contribute to its digest. Existing Unicode
45
+ behavior, including UTF-8 replacement of a terminal high surrogate, is retained
46
+ exactly. No values are silently clipped.
47
+
48
+ Limits remain 32 keys, 512 bytes per key value, 8192 combined key/value bytes,
49
+ 16384 identity bytes, 256 targets, 262144 projection bytes. Presentation limits
50
+ remain 256 label bytes, 1024 detail bytes, 2048 URL bytes and 4096 total bytes.
51
+ BB identities retain installation-local project, project/thread, and the fixed
52
+ Machine Monitor page shapes. URL identity is canonical HTTP(S), without
53
+ credentials or credential-shaped query/fragment parameters.
54
+
55
+ `normalizeThreadOrUrlReference(target)` uses these central bounds and permits
56
+ exact BB thread or safe URL resources. A supplied native presentation URL must
57
+ match `/projects/{project}/threads/{thread}` or `/threads/{thread}`. Callers own additional label and count
58
+ policy. `urlResource` serializes a URL; canonicalization validates it. Shared
59
+ picker helpers preserve Machine Monitor's reference-label messages and bounds.
60
+
61
+ `ReferenceSnapshot` (alias `AttachmentSnapshot`) is
62
+ `{revision,targets,status:{state:"synced"|"pending"|"degraded"|"blocked",
63
+ error:string|null}}`. It adapts feature storage for controls; it does not replace
64
+ Machine Monitor's wire attachment response/status.
65
+
66
+ ## Fixed RPC and negotiation
67
+
68
+ `crossReferencesRpcSchemas` adds only `crossReferences.describe`: null input,
69
+ `{protocol:"cross-references",versions:[1]}` output. Its envelope tolerates extra
70
+ fields, bounds versions to 16 positive safe integers, and negotiates v1 when
71
+ advertised. No shared version raises `CrossReferencesProtocolError`. Only
72
+ transport `code:"unknown_method"` permits legacy v1 fallback; absent/disabled
73
+ peers, ordinary 404s, timeouts and malformed output fail. Describe is explicit;
74
+ clients perform no hidden listing, discovery or caching. Consumers own listing
75
+ and probing, or use the explicit central default.
76
+
77
+ Legacy methods stay `applyProjection`, `getProjection`, `listBacklinks`,
78
+ `listForwardReferences`, `checkForwardReferences`. Their strict schemas, DTOs,
79
+ identity, digest and CAS meanings are unchanged. Legacy strict outputs are a
80
+ compatibility constraint; new envelopes tolerate extension. Central registration
81
+ wraps shared schemas with existing `defineRpcContract` and supplies the fixed
82
+ describe handler. Changed wire meaning requires a new versioned method.
83
+
84
+ Every client call validates input before transport, targets the injected plugin
85
+ ID, passes abort, and enforces 1000 ms describe / 5000 ms other deadlines. Options
86
+ can lower those budgets only. Promise races enforce bounds even for transports
87
+ ignoring abort; listeners and timers are cleaned up. Decoded canonical JSON is
88
+ capped at 1048576 bytes before DTO parsing. The SDK already parses the envelope,
89
+ so raw transport byte admission remains outside this package's guarantee.
90
+
91
+ Transport errors retain their codes. `timeout` denotes deadline failure,
92
+ `incompatible_protocol` negotiation/result admission failure, and Zod errors
93
+ malformed data. Features classify these within their existing failure policy.
94
+ Clients never retry writes or attribute success after an unknown outcome.
95
+ Direct writes require a fresh read reconciled by submitted digest; durable
96
+ outbox policy remains feature-owned.
97
+
98
+ ## Release and proof
99
+
100
+ Consumers pin `@phosphorco/bb-cross-references` exactly at `0.1.0`. Runtime pins
101
+ are Zod 4.3.6 and @noble/hashes 1.8.0. SDK and React are optional external peers.
102
+ Bun.build emits root, bb, react and testing with production automatic JSX,
103
+ followed by declarations and the CSS copy. Testing sibling entries stay external
104
+ so the conformance kit uses the same production module instance. Do not commit
105
+ `dist`.
106
+
107
+ Package self-tests, adopter source conformance, UI/host proof and live composition
108
+ are separate evidence levels. Rendering, dependency locks, publication and live
109
+ proof are owned by the coordinating lane.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Phosphor
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,42 @@
1
- # Temporary Holding Version
1
+ # @phosphorco/bb-cross-references
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Cross References v1 resources, browser-safe synchronous canonical hashes,
4
+ wire schemas, explicit SDK clients and shared reference controls. Each feature
5
+ owns its storage, delivery and attachment policy.
6
+
7
+ ```ts
8
+ import { threadResource } from "@phosphorco/bb-cross-references";
9
+ import { createCrossReferencesClient } from "@phosphorco/bb-cross-references/bb";
10
+
11
+ const reference = threadResource("proj_example", "thr_example", { label: "Investigation" });
12
+ const client = createCrossReferencesClient(sdk, "cross-references");
13
+ await client.describe();
14
+ const backlinks = await client.listBacklinks({
15
+ target: { provider: reference.provider, keys: reference.keys },
16
+ });
17
+ ```
18
+
19
+ Optional UI: `/react`; stylesheet: `/styles.css`. Controls receive injected APIs.
20
+
21
+ ```tsx
22
+ import { LinkedReferences } from "@phosphorco/bb-cross-references/react";
23
+ import "@phosphorco/bb-cross-references/styles.css";
24
+
25
+ <LinkedReferences ownerKey="my-plugin:settings" api={localReferencesApi}
26
+ navigateThread={navigate.toThread} connection={connection} refreshToken={revision} />;
27
+ ```
28
+
29
+ The API implements `get`, `replace(revision,targets)`, `search(query)`, and
30
+ `thread(threadId)` over your own storage. Change ownerKey when switching storage
31
+ owners. The editor preserves local CAS, refreshes after uncertain writes without
32
+ resending them, debounces thread search, and shows escaped delivery diagnostics.
33
+ It performs no central graph calls or idle polling.
34
+ The snapshot DTO is `ReferenceSnapshot`, also exported as `AttachmentSnapshot`.
35
+
36
+ Use `/testing`'s `runCrossReferencesConformance({sdk, pluginId?, command})` with
37
+ an isolated fixture and the adopter's real registered handlers. It drives
38
+ client apply/get/backlinks acceptance and reports source conformance.
39
+
40
+ Run `npm run build`, `npm run test`, `npm run typecheck` in the workspace.
41
+ See [CONTRACT.md](./CONTRACT.md) for exports, bounds, wire compatibility,
42
+ legacy describe fallback and proof limitations.