@webex/internal-plugin-device 3.12.0-next.54 → 3.12.0-next.56

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.
@@ -0,0 +1,237 @@
1
+ ---
2
+ type: Architecture
3
+ title: '@webex/internal-plugin-device architecture'
4
+ description: Boundaries, resources, interactions, dependencies, and cross-cutting architecture of the Webex JS SDK device plugin package.
5
+ tags: [architecture]
6
+ ---
7
+ <!-- sdd-generated-metadata
8
+ doc_kind: standing-doc
9
+ generated_from: architecture@0.3.0
10
+ generated_by: claude-code
11
+ approved_by: riag@cisco.com
12
+ updated_at: 2026-10-07T15:08:52Z
13
+ validation_status: pass
14
+ -->
15
+
16
+ # @webex/internal-plugin-device architecture
17
+
18
+ Canonical architecture for the `@webex/internal-plugin-device` package, an internal plugin of the Webex JS SDK
19
+ monorepo. The SDD scope is this package only; the surrounding monorepo is a dependency context, not part of this
20
+ document. Owner-local detail lives in the [module specification](../src/docs/README.md).
21
+
22
+ Related context: [specification registry](specs/README.md) ·
23
+ [repository agent instructions](../AGENTS.md)
24
+
25
+ ## Applicability
26
+
27
+ | Condition ID | Status | Evidence or reason | Owned section |
28
+ | ------------------------------------ | ---------- | ------------------------------------------------------------------------------------------------------ | ----------------------------------- |
29
+ | `repo.owns_datastore` | N/A | No store, schema, or migration exists in src/; storage is delegated to @webex/webex-core | Repository data and schema |
30
+ | `repo.holds_client_state` | Applicable | `src/device.js` keeps registration, session, and feature state in memory | Client state model |
31
+ | `repo.components_interact` | Applicable | `src/index.js` wires the plugin, interceptor, and webex.internal collaborators together | Dependency and interaction topology |
32
+ | `repo.domain_data_across_components` | N/A | One writer: `src/device.js` owns the device data; other plugins only read it | Object and data ownership |
33
+ | `repo.caches_data` | Applicable | Persisted device state and the etag-based feature cache in `src/device.js` | Caching catalog |
34
+ | `repo.observability_convention` | Applicable | device:-prefixed logs, internal events, and client metrics in `src/device.js` and `src/metrics.js` | Observability patterns |
35
+ | `repo.deploys_to_infra` | N/A | A library; `package.json` defines no deployment target other than npm publication | Runtime and infrastructure |
36
+ | `repo.shared_base_libs` | N/A | No base library stack is inherited by multiple resources inside this package | Shared and base libraries |
37
+ | `repo.is_monorepo` | N/A | The scoped repository is a single package with one module | Package map and dependencies |
38
+ | `repo.multi_platform` | Applicable | Browser and Node targets: `src/config.js` branches on inBrowser, `package.json` has test:browser | Platform matrix |
39
+ | `repo.published_package` | Applicable | `package.json` declares main and deploy:npm | Release and versioning |
40
+ | `repo.embedded_in_host` | N/A | A plugin of @webex/webex-core, not mounted into a host UI | Host integration and theming |
41
+ | `repo.exposes_commands_or_artifacts` | N/A | No CLI, generator, or stable file output; `package.json` scripts are developer tooling | Commands and generated artifacts |
42
+ | `repo.cross_repo_deps_material` | N/A | All dependencies resolve inside the same workspace or npm | Cross-repository topology |
43
+ | `repo.security_arch_warranted` | N/A | No credential, token, or encryption handling in src/; identity-header rule is covered under Security | Security architecture |
44
+
45
+ ## Design overview
46
+
47
+ The package gives every Webex SDK instance one **registered device**: a server-side record at the WDM
48
+ (web device manager) service that other Webex services key on, plus the local state returned with it — device and
49
+ WebSocket URLs, feature toggles, and organization policy. It exists as a separate plugin because dozens of other
50
+ plugins need that registration before they can talk to the backend, but the registration itself is
51
+ independent of messaging, meetings, or calling.
52
+
53
+ Shape: one Ampersand model (`Device`) registered as `webex.internal.device`, owning two children (a
54
+ three-collection feature container and an IP-network detector) and one request interceptor that stamps
55
+ outbound requests with the device URL. Registration is request/response against WDM with three lifecycle
56
+ operations (register, refresh, unregister), a self-healing path for expired registrations (404 on refresh) and
57
+ for the per-user device limit (cleanup then retry). Local policy logic (inactivity logout and intranet
58
+ reachability) hangs off properties delivered in the same payload.
59
+
60
+ Key decisions evidenced in the code: callers need not know registration state because `register()` and `refresh()`
61
+ delegate to each other; concurrent calls share one in-flight request; unknown WDM fields are tolerated so backend
62
+ additions do not break clients; and responses arriving after a logout are discarded. Details are in the module
63
+ specification.
64
+
65
+ ## Resource inventory and responsibilities
66
+
67
+ | Resource | Kind | Responsibility | Owner | Source | Detailed specification |
68
+ | ------------------------------ | ------------------------- | --------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ------ | ----------------------- |
69
+ | `@webex/internal-plugin-device` | package (single module `src`) | Device registration lifecycle, device-derived state, `cisco-device-url` header, IP network detection | Webex JS SDK maintainers | src/ | `src/docs/README.md` |
70
+
71
+ ## Interaction and execution flows
72
+
73
+ Representative flow: a client authenticates, the device registers, other plugins use the device URL and
74
+ WebSocket URL, and logout unregisters.
75
+
76
+ ```mermaid
77
+ flowchart LR
78
+ Auth[Authenticated webex instance] --> Reg[Device.register]
79
+ Reg --> Cat[services catalog: wdm]
80
+ Cat --> WDM[WDM service]
81
+ WDM --> State[Device state and features]
82
+ State --> Event[registration:success]
83
+ Event --> Mercury[Other plugins: websocket url, features]
84
+ State --> Header[DeviceUrlInterceptor adds cisco-device-url]
85
+ Auth -->|logout| Unreg[Device.unregister via onBeforeLogout]
86
+ Unreg --> WDM
87
+ ```
88
+
89
+ | From | To | Interaction or transport | Purpose | Failure or compatibility behavior |
90
+ | --------------------- | ------------------------------ | ---------------------------------------------------------------- | ----------------------------------------------- | ---------------------------------------------------------------------------------- |
91
+ | Device | WDM service | HTTP through `webex.request` (POST, PUT, GET, DELETE) | Create, keep, list, and remove registrations | 404 on refresh re-registers; excessive-registration error triggers cleanup and one retry |
92
+ | Device | services plugin | Promise calls for catalog readiness and priority-host mapping | Resolve `wdm` and the WebSocket host | Missing `wdm` rejects registration |
93
+ | DeviceUrlInterceptor | services plugin | `waitForService` and `getServiceFromUrl` on each request | Decide whether to attach the header | Not-found-after-waiting is swallowed; other errors reject the request |
94
+ | Device | metrics plugins | Direct method calls | Time and count registrations | Not guarded in this package |
95
+ | Other plugins | Device | Property reads, events (`registration:success`, `change:features`) | Obtain device URL, WebSocket URL, feature toggles | Property names are relied on across the SDK |
96
+
97
+ ## Dependency topology
98
+
99
+ | Dependency | Type | Used by | Purpose | Version, failure, or fallback policy |
100
+ | ----------------------------------- | -------- | ------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------------------- |
101
+ | `@webex/webex-core` | Internal | Device, helpers | Plugin base, storage decorators, request pipeline, services | Workspace-linked (`workspace:*` in `package.json`); no fallback |
102
+ | `@webex/internal-plugin-metrics` | Internal | Device | Internal events and client metrics | Workspace-linked; imported for its side effects |
103
+ | `@webex/common` | Internal | Device, config | `oneFlight`, `deprecated`, `inBrowser`, `deviceType` | Workspace-linked |
104
+ | `@webex/common-timers` | Internal | Device | `safeSetTimeout` | Workspace-linked |
105
+ | `@webex/http-core` | Internal | Interceptor | `Interceptor` base class | Workspace-linked |
106
+ | `ampersand-state`, `ampersand-collection` | External | Device, features | Model and collection runtime | Pinned by range in `package.json` |
107
+ | `lodash`, `uuid` | External | Device, features, interceptor | Utilities and request-id generation | Pinned by range in `package.json` |
108
+ | WDM service | External | Device | Registration system of record | Reached through the `wdm` catalog entry; no local fallback |
109
+ | Browser `RTCPeerConnection` | External | IP network detector | ICE candidate gathering | Browser only; detection fails elsewhere |
110
+
111
+ No dependency cycle exists inside the package. A runtime cycle exists across packages: the device plugin calls
112
+ the metrics plugin while the metrics plugin is handed the device through `setDeviceInfo`, a method added to avoid a
113
+ circular import (source comment in `@webex/internal-plugin-metrics`). Ordering constraint: `src/index.js` imports the
114
+ metrics plugin before registering the device plugin. Exact versions are in `package.json`.
115
+
116
+ ## Public and consumer surfaces
117
+
118
+ Dependency specifications were used where present (`@webex/common`, `@webex/common-timers`, `@webex/http-core`);
119
+ `@webex/webex-core` and `@webex/internal-plugin-metrics` have none, so their source was used.
120
+
121
+ | Surface | Type | Owner | Consumers | Compatibility policy | Source |
122
+ | -------------------------------------------------------------------------------- | ----- | ------------------------------- | -------------------------------------------------- | --------------------------------------------------------------------------------------------------------- | -------------------------------- |
123
+ | `device-plugin-sdk` (npm exports and `webex.internal.device` API) | SDK | `@webex/internal-plugin-device` | SDK plugins, calling and meetings packages, clients | Internal; semantic versioning not strictly followed (README); renames break dependent packages | `package.json` |
124
+ | `device-registration-events` (`registration:success`, `change`, `change:features`, `change:<collection>`) | Event | `@webex/internal-plugin-device` | Plugins listening on the device | Names relied on internally; names are declared in `src/constants.js`, emitted from `src/device.js` and `src/features/features-model.js` | `src/device.js` |
125
+ | `cisco-device-url-header` | API | `@webex/internal-plugin-device` | Webex backend services | Internal; excluded for `idbroker`, `oauth`, `saml` | `src/interceptors/device-url.js` |
126
+
127
+ The contract registry with publication state is `contract_catalog` in `.sdd/manifest.json`; the owning module
128
+ specification, [Public surface](../src/docs/README.md#public-surface), mirrors these entries.
129
+
130
+ ## Client state model
131
+
132
+ | State or slice | Owner | Transition triggers | Persistence or reset boundary |
133
+ | ------------------------------- | --------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------ |
134
+ | Registration and WDM DTO props | `Device` | register, refresh, unregister, clear | Persisted unless the device is ephemeral; cleared on logout |
135
+ | Feature toggles | `FeaturesModel` collections | Registration responses, debug toggles | Reset by `clear()` |
136
+ | Inactivity and meeting session | `Device` session props | Setting changes, meeting events, user activity | Session only |
137
+ | IP detection results | `IpNetworkDetector` | `detect()` | Reset at the start of each detection |
138
+
139
+ ## Cross-cutting architecture
140
+
141
+ ### Security
142
+
143
+ - Trust boundaries and identity flow: authentication and tokens are handled by `@webex/webex-core`; this package
144
+ forwards device identity only through the `cisco-device-url` header, which must not reach `idbroker`, `oauth`, or
145
+ `saml` services (`src/interceptors/device-url.js`).
146
+ - Sensitive surfaces and data classes: the device URL and user/organization identifiers stored on the device;
147
+ debug feature toggles are read from `sessionStorage` under a caller-configured key (`src/device.js`).
148
+ - Encryption and secret boundaries: no secrets or cryptography in this package; transport security belongs to the
149
+ request pipeline.
150
+
151
+ ### Observability and operations
152
+
153
+ - Logging and correlation: logs go through the plugin logger with a `device:` message prefix; registration
154
+ request and response are timestamped through internal events for call diagnostics (`src/device.js`).
155
+ - Metrics, traces, and audit signals: client metrics for registration success and failure (`src/metrics.js`); no
156
+ traces or audit events.
157
+ - Ownership and operational entry points: no dashboards, alerts, or runbooks are defined in this package.
158
+
159
+ ### Quality attributes
160
+
161
+ - Footprint: timers use `safeSetTimeout` so refresh and logout timers do not keep a Node process alive.
162
+ - Compatibility: Node engine floor declared in `package.json`; browser behavior covered by a Karma target and the
163
+ `process` file marks the package as browser-capable.
164
+ - Verification: unit and integration suites under `test/`; no coverage threshold is enforced in this package.
165
+
166
+ ## Dependency and interaction topology
167
+
168
+ ```mermaid
169
+ flowchart LR
170
+ Index[src/index.js] -->|registerInternalPlugin| Core[webex-core]
171
+ Index -->|interceptors| Interceptor[DeviceUrlInterceptor]
172
+ Index -->|side-effect import| Metrics[internal-plugin-metrics]
173
+ Device[Device] --> Features[FeaturesModel]
174
+ Device --> Detector[IpNetworkDetector]
175
+ Device -->|request| Core
176
+ Device -->|submit| Metrics
177
+ Device -->|safeSetTimeout| Timers[common-timers]
178
+ Device -->|oneFlight, deprecated| Common[common]
179
+ Interceptor -->|extends| Http[http-core Interceptor]
180
+ Device -->|events| Consumers[Other plugins]
181
+ ```
182
+
183
+ | From | To | Kind | Purpose | Ordering or failure boundary |
184
+ | -------------------- | ------------------------- | ------ | ----------------------------------------------- | -------------------------------------------------------------------------------- |
185
+ | `src/index.js` | `@webex/webex-core` | Call | Register plugin, interceptor, logout hook | At import time |
186
+ | `src/index.js` | metrics plugin | Import | Make metrics available before registration | Must precede plugin registration |
187
+ | Device | Features, detector | Import | Own child models | Constructed with the device |
188
+ | Device | Other plugins | Event | Announce registration and feature changes | `registration:success` fires after state is stored |
189
+ | Interceptor | Services plugin | Call | Resolve the target service of each request | Waits for the catalog; errors other than not-found reject the request |
190
+
191
+ ## Caching catalog
192
+
193
+ | Cache | Owner | Backend | Contents | TTL or bound | Invalidation trigger | Failure behavior |
194
+ | -------------------------- | -------- | ------------------------------- | -------------------------------------------------- | --------------------------------------------- | -------------------------------------------------------- | ----------------------------------------- |
195
+ | Persisted device | `Device` | `@webex/webex-core` bounded storage via `@persist` | Whole device model including `etag` | None in this package | `clear()`; not written at all when ephemeral | Missing storage means a fresh registration |
196
+ | Feature toggle etag cache | `Device` | WDM conditional request (`If-None-Match`) | Developer feature toggles retained across refreshes | Until the etag changes | Etag mismatch, first `change:config` with debug toggles | Mismatch falls back to full response |
197
+
198
+ ## Observability patterns
199
+
200
+ | Signal | Convention or required fields | Propagation or naming rule | Primary evidence |
201
+ | ------- | -------------------------------------------------------------------------- | ------------------------------------------------------------ | ---------------------- |
202
+ | Logs | `device: <message>` through `this.logger`; errors logged with the error object | Logger supplied by the webex instance | `src/device.js` |
203
+ | Metrics | `JS_SDK_WDM_REGISTRATION_SUCCESSFUL`, `JS_SDK_WDM_REGISTRATION_FAILED` | Constants exported from one module | `src/metrics.js` |
204
+ | Traces | None | N/A | `src/device.js` |
205
+ | Audit | None | N/A | `src/device.js` |
206
+
207
+ ## Platform matrix
208
+
209
+ | Platform | Shared versus platform-specific boundary | Entry or build | Support and compatibility constraints |
210
+ | -------- | ------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------- |
211
+ | Browser | Same sources; default device name falls back to `browser`; IP network detection works here only | `package.json` scripts `test:browser` | `RTCPeerConnection` required for detection |
212
+ | Node | Same sources; device name defaults to the process title | `package.json` `main` and `test:unit` | Engine floor in `package.json`; no WebRTC, so detection is unavailable |
213
+
214
+ ## Release and versioning
215
+
216
+ | Artifact | Publish target | Versioning rule | Deprecation window | Changelog or migration obligation |
217
+ | -------------------------------- | -------------- | -------------------------------------------------------------------- | --------------------------------- | ---------------------------------------------------- |
218
+ | `@webex/internal-plugin-device` | npm (`deploy:npm` script in `package.json`) | Internal plugin; README states semantic versioning is not strictly followed | None defined; deprecation via `@deprecated` decorator | None defined in this package |
219
+
220
+ ## Domain language
221
+
222
+ | Term | Repository-specific meaning | Authoritative source |
223
+ | ---------- | ---------------------------------------------------------------------------------------- | ----------------------------------- |
224
+ | WDM | Web device manager: the Webex service that stores device registrations | `src/device.js` |
225
+ | Device | This client's registration at WDM plus its local state, `webex.internal.device` | `src/device.js` |
226
+ | Ephemeral | Registration created with a TTL and refreshed on a timer instead of persisted | `src/config.js` |
227
+ | Feature | A named toggle from WDM in one of `developer`, `entitlement`, `user`, typed on parse | `src/features/feature-model.js` |
228
+ | Catalog | The services catalog that maps service names to hosts; `wdm` must be present | `src/device.js` |
229
+
230
+ ## References and maintenance
231
+
232
+ - Decisions: [adr/](adr/index.md)
233
+ - Instantiated specifications and routing: [specs/README.md](specs/README.md)
234
+ - Repository rules and patterns: none approved for this package.
235
+ - Update this document in the same change that alters repository boundaries,
236
+ resource ownership, cross-resource interaction, or cross-cutting
237
+ architecture.
@@ -0,0 +1,91 @@
1
+ ---
2
+ type: Getting Started
3
+ title: Getting started
4
+ description: Local setup, build, run, and test routing for @webex/internal-plugin-device.
5
+ tags: [onboarding]
6
+ ---
7
+ <!-- sdd-generated-metadata
8
+ doc_kind: standing-doc
9
+ generated_from: getting-started@0.3.0
10
+ generated_by: claude-code
11
+ approved_by: riag@cisco.com
12
+ updated_at: 2026-10-07T15:08:52Z
13
+ validation_status: pass
14
+ -->
15
+
16
+ # Getting started
17
+
18
+ Onboarding for **@webex/internal-plugin-device**, a package inside the Webex JS SDK Yarn workspace. All
19
+ commands below run from the monorepo root through `yarn workspace`.
20
+
21
+ ## Prerequisites
22
+
23
+ | Tool or access | Version or requirement |
24
+ | --------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
25
+ | Node.js | `>=18` per this package's `engines`; use the version the monorepo root `AGENTS.md` pins for repository work |
26
+ | Yarn workspaces | Provided by the monorepo root; this package declares its workspace dependencies with `workspace:*` |
27
+ | Webex test-user provisioning (integration only) | Required by `@webex/test-helper-test-users`; credentials come from the monorepo's environment setup, not this package |
28
+
29
+ ## Install
30
+
31
+ Dependencies are installed once for the whole workspace from the monorepo root (the package defines no install
32
+ script of its own).
33
+
34
+ ## Build
35
+
36
+ ```bash
37
+ yarn workspace @webex/internal-plugin-device build:src
38
+ ```
39
+
40
+ ## Run
41
+
42
+ This package is a library with no process to start. Consumers import it for its side effect and then use
43
+ `webex.internal.device`, as shown in the package [README](../README.md).
44
+
45
+ ## Tests
46
+
47
+ ```bash
48
+ yarn workspace @webex/internal-plugin-device test:unit
49
+ ```
50
+
51
+ Use the table as the package-level test router. Behavioral intent belongs in the
52
+ [module specification](../src/docs/README.md); exact cases remain in the native test sources.
53
+
54
+ | Tier | Command | Test location | Framework | External dependencies |
55
+ | ----------------------------- | ------------------------------------------------------------- | -------------------- | ---------------------- | -------------------------------------------------------------- |
56
+ | Unit | `yarn workspace @webex/internal-plugin-device test:unit` | `test/unit` | Jest | None |
57
+ | Integration (browser runner) | `yarn workspace @webex/internal-plugin-device test:browser` | `test/integration` | Mocha through Karma | Provisioned Webex test users and network access to Webex services |
58
+ | Style | `yarn workspace @webex/internal-plugin-device test:style` | `src` | ESLint | None |
59
+
60
+ - Coverage or quality gate: none known for this package (owner-confirmed absence of a repo-specific gate).
61
+ - Enforcement source: none.
62
+ - Test environment or QA dependencies: integration specs create real test users; no manual QA tracker is
63
+ recorded.
64
+
65
+ ## Configuration and secrets
66
+
67
+ - Required configuration: none for unit tests. Runtime behavior is configured under `webex.config.device`; the
68
+ defaults are in `src/config.js`.
69
+ - Secret source: integration tests obtain credentials through the test-user helper; no secret is stored in this
70
+ package.
71
+ - Package or artifact access: workspace packages resolve locally; publishing uses `yarn workspace @webex/internal-plugin-device deploy:npm`.
72
+ - Required neighboring repositories or workspace layout: this package must stay inside the Webex JS SDK
73
+ workspace so its `workspace:*` dependencies resolve.
74
+ - Platform, simulator, device, or SDK setup: the browser tier needs a browser available to Karma; IP network
75
+ detection needs WebRTC and is not exercised under Node.
76
+ - Never commit credentials or copy production secrets into a local config.
77
+
78
+ ## First-run verification
79
+
80
+ 1. Run `yarn workspace @webex/internal-plugin-device test:unit`.
81
+ 2. Check that every suite reports a pass and no failures.
82
+ 3. Run `yarn workspace @webex/internal-plugin-device test:style` for the lint check.
83
+
84
+ Expected result: all six unit suites pass and ESLint reports zero errors (it currently prints warnings, including a
85
+ warning that `src/docs/README.md` is ignored by the lint patterns).
86
+
87
+ ## Next steps
88
+
89
+ - [Package architecture](architecture.md)
90
+ - [Specification registry](specs/README.md)
91
+ - [Documentation index](index.md)
package/docs/index.md ADDED
@@ -0,0 +1,40 @@
1
+ ---
2
+ okf_version: '0.1'
3
+ ---
4
+ <!-- sdd-generated-metadata
5
+ doc_kind: standing-doc
6
+ generated_from: docs-index@0.3.0
7
+ generated_by: claude-code
8
+ approved_by: riag@cisco.com
9
+ updated_at: 2026-10-07T15:08:52Z
10
+ validation_status: pass
11
+ -->
12
+
13
+ # @webex/internal-plugin-device documentation
14
+
15
+ Doc map for developers and agents working on the Webex JS SDK device plugin package.
16
+
17
+ ## Start here
18
+
19
+ - [Getting started](getting-started.md)
20
+ - [Package architecture](architecture.md)
21
+
22
+ ## Decisions
23
+
24
+ - [adr/](adr/index.md) — architectural decision records
25
+
26
+ ## Specifications and contracts
27
+
28
+ - [architecture.md](architecture.md) — canonical package architecture and the contract index
29
+ - [specs/README.md](specs/README.md) — manifest-backed module and contract registry
30
+ - [src/docs/README.md](../src/docs/README.md) — the owning specification beside the module's code
31
+ - [adr/](adr/index.md) — concrete architectural decisions; blank ADR templates remain under the repository's `.sdd/` templates
32
+
33
+ No service specification or OpenAPI document exists: this package is a library, not a deployable service, and it
34
+ owns no HTTP contract. The published SDK surface is described by `package.json` and the module's `Public surface`
35
+ section; it is registered in the architecture index rather than copied into Markdown.
36
+
37
+ ## Related repository resources
38
+
39
+ The package README ([../README.md](../README.md)) is the original usage guide and remains the consumer-facing
40
+ introduction. No `ci/`, `operate/`, runbook, or diagram folders exist for this package.
@@ -0,0 +1,80 @@
1
+ ---
2
+ type: Reference
3
+ title: Specification registry
4
+ description: Canonical specification registry and change-routing guide.
5
+ tags: [specifications, registry]
6
+ ---
7
+ <!-- sdd-generated-metadata
8
+ doc_kind: standing-doc
9
+ generated_from: spec-index@0.3.0
10
+ generated_by: claude-code
11
+ approved_by: riag@cisco.com
12
+ updated_at: 2026-10-07T15:08:52Z
13
+ validation_status: pass
14
+ -->
15
+
16
+ # Specification registry
17
+
18
+ Use this page to find the canonical architecture for `@webex/internal-plugin-device` and every instantiated
19
+ module specification plus native contract. Technical facts stay in one owning document; this page is
20
+ navigation, ownership, status, and change/test routing only.
21
+
22
+ Start with the [package architecture](../architecture.md). There is no service specification: the package is a
23
+ published library, not a deployable service.
24
+
25
+ ## Document roles
26
+
27
+ | Document | Canonical ownership |
28
+ | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- |
29
+ | [Package architecture](../architecture.md) | Package boundaries, resource inventory, interactions, dependency topology, and cross-cutting architecture |
30
+ | Service specification | N/A — not generated; the package has no deployable runtime, so no service or operating contract exists |
31
+ | Module specifications | Stable behavior and design at each module's canonical spec path, routed by `.sdd/manifest.json` |
32
+ | [ADR](../adr/index.md) | A durable decision, its deciders, rationale, consequences, and supersession lineage; none are registered yet |
33
+
34
+ ## Instantiated specification registry
35
+
36
+ | Resource | Role | Canonical path | Owner | Status | Last verified |
37
+ | ------------------------------- | ------------ | -------------------------------- | ------------------------ | ------ | ------------- |
38
+ | Repository | Architecture | `docs/architecture.md` | Webex JS SDK maintainers | Draft | 2026-10-07 |
39
+ | `src` | Module | `src/docs/README.md` | Webex JS SDK maintainers | Draft | 2026-10-07 |
40
+ | `device-plugin-sdk` | Contract | `package.json` | Webex JS SDK maintainers | Draft | 2026-10-07 |
41
+ | `device-registration-events` | Contract | `src/device.js` | Webex JS SDK maintainers | Draft | 2026-10-07 |
42
+ | `cisco-device-url-header` | Contract | `src/interceptors/device-url.js` | Webex JS SDK maintainers | Draft | 2026-10-07 |
43
+
44
+ ### Module registry
45
+
46
+ One row per module in `.sdd/manifest.json`, which stays authoritative; this table is its
47
+ human-readable mirror and the reconciliation surface for `check_spec_index.py`.
48
+
49
+ | Module | Responsibility | Manifest coverage state | Start here |
50
+ | --- | --- | --- | --- |
51
+ | `src/` | Device registration with the WDM service (register, refresh, unregister, stale-device cleanup), device-derived state and feature toggles, the `cisco-device-url` request header, inactivity logout, and IP network detection | Partial | `src/docs/README.md` |
52
+
53
+ Generator-side field measurement for `src` is complete: 80.0% (12 of 15 mandatory fields) assessed 2026-10-07,
54
+ with critical field coverage at 6 of 7. The score, date, and evidence summary are recorded in the module
55
+ specification's `Coverage score` metadata row and in `.sdd/manifest.json`. Independent validation returned `pass`
56
+ for this documentation set; that is separate from the coverage measurement.
57
+
58
+ Three fields remain weak. The external WDM integration has no committed machine-readable contract and the owner
59
+ has stated none can be provided, so it is recorded as an approved unknown. The design rationale needs owner input
60
+ (no ADR exists). Test and characterization coverage lacks a baseline, and `MOD-015`, `MOD-026`, `INV-004`, and
61
+ `INV-005` have no automated evidence. Promotion to `Specced` stays held while a critical field is weak and no drift
62
+ measurement exists. The improvement decision recorded for this onboarding is `deferred`.
63
+
64
+ ## Change and verification routing
65
+
66
+ | Change affects | Load and update | Verification route |
67
+ | ------------------------------------------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------ |
68
+ | Package boundaries or cross-cutting architecture | `docs/architecture.md` and applicable ADRs | Package test routing and affected owner specs |
69
+ | A stable code, package, or component boundary | The module spec `src/docs/README.md` | Module tests plus affected contracts |
70
+ | A public API, event, or header contract | The owning architecture/module section plus the native source named in the registry above | Unit tests and the dependent-package integration suites |
71
+
72
+ ## Module and contract registration
73
+
74
+ The module specification is generated at the exact `modules[].canonical_spec` path recorded in
75
+ `.sdd/manifest.json`. Every module and submodule appears in the Module registry above in manifest tree order.
76
+
77
+ Each contract has a stable identity, a `published` or `internal` publication state, a canonical native source,
78
+ and an owning-module link in `contract_catalog`. This package owns no HTTP surface, so no OpenAPI source applies:
79
+ its published SDK surface keeps its ecosystem-native source, `package.json` plus the sources it names. This page
80
+ provides navigation and ownership rather than a copied contract.
package/package.json CHANGED
@@ -39,8 +39,8 @@
39
39
  "@webex/common": "3.12.0-next.9",
40
40
  "@webex/common-timers": "3.12.0-next.10",
41
41
  "@webex/http-core": "3.12.0-next.9",
42
- "@webex/internal-plugin-metrics": "3.12.0-next.54",
43
- "@webex/webex-core": "3.12.0-next.54",
42
+ "@webex/internal-plugin-metrics": "3.12.0-next.57",
43
+ "@webex/webex-core": "3.12.0-next.61",
44
44
  "ampersand-collection": "^2.0.2",
45
45
  "ampersand-state": "^5.0.3",
46
46
  "lodash": "^4.17.21",
@@ -55,5 +55,5 @@
55
55
  "test:style": "eslint ./src/**/*.*",
56
56
  "test:unit": "webex-legacy-tools test --unit --runner jest"
57
57
  },
58
- "version": "3.12.0-next.54"
58
+ "version": "3.12.0-next.56"
59
59
  }