Commit Graph
10 Commits
Author SHA1 Message Date
ClintchizandClaude Opus 5 69020b2555 docs: make the component sections executable in one pass
Quality / quality (ubuntu-latest) (push) Failing after 10m7s
Quality / quality (windows-latest) (push) Canceled after 0s
Expands 3.1 and 3.2 so the work can be done without re-deriving anything.

3.1 now records what 0.8.6 already fixed, separated into the ten components
that were miswired and the five that gained outputs they had been firing
undeclared, with the caveat that Map's three were converted but never confirmed
in a browser. For the 22 that remain it adds the finding that changes the
decision: all nine are pure scaffolds with no state, functions or handlers, and
five of them duplicate a component that already works -- FileUpload against
FileInput and FileUploadProgress, Toast and ToastNotifications against Toaster,
AdvancedDatePicker against DatePicker, AdvancedRangeSlider against RangeSlider.
Superseding those is a migration entry rather than new code, and leaves Chart,
TreeView, Confetti and CopyMarkup as the only ones needing to be built.

3.2 corrects the scaffold count from 23 to 28; the earlier figure used a looser
rule. Nine of the 28 are the 3.1 components, so the two items must be planned
together, and several of the rest are primitives that need only their styles
moved out of ui.css rather than any behaviour.

Also corrects the dead-output component count from 11 to 9 in both documents.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 10:34:22 +05:30
ClintchizandClaude Opus 5 9ed896d2b9 docs: correct the dead-output component count from 11 to 9
Quality / quality (ubuntu-latest) (push) Failing after 12m8s
Quality / quality (windows-latest) (push) Canceled after 0s
Counted from source: the 22 remaining outputs sit in 9 components, not 11.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 10:14:28 +05:30
ClintchizandClaude Opus 5 5112cc1a62 docs: measure the runtime and the generated client modules
Quality / quality (ubuntu-latest) (push) Failing after 13m21s
Quality / quality (windows-latest) (push) Canceled after 0s
Adds a per-subsystem measurement of reactive.js, made by minifying it
repeatedly with one subsystem removed rather than counting source bytes.

This corrects the earlier audit on both figures and on the conclusion drawn
from them. Component controllers are 23,722 bytes minified / 6,660 gzipped --
30.6% of transfer, not the "about 18%" previously claimed -- and splitting them
out saves 6.6 kB gzipped on a typical page, not "3-4 kB". Measured against the
example app, / and /login use none of the ten controllers and /layout uses one,
so most pages download and parse the lot for nothing.

The larger finding is that the runtime is not where the weight is. One page
parses 490,212 decoded bytes across 11 generated client modules while
transferring 21,026, and the largest module is 89.8% duplicated lines: the
state-restore prologue appears 162 times because client-codegen.ts inlines the
sync into every peer alias of every client function. Gzip hides it on the wire,
but parse cost follows decoded bytes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 10:02:36 +05:30
ClintchizandClaude Opus 5 3eec9fd8c6 fix(rpc): close the four final-review blockers on inter-app RPC
- Resolve RPC call origins via a new WRNEXUS_INTERNAL_ORIGINS map (loopback
  origins the gateway hands each child before spawning it), falling back to
  the public appOrigin only when it is absent. Calls previously always went
  to the public gateway origin, which the gateway unconditionally 404s on
  the RPC prefix by design — every real cross-app call failed.
- Stop loadServices() from running ahead of routing and stop memoizing a
  rejected load: one bad file under app/services/ no longer permanently
  breaks every route in the app. A failed load logs loudly, is retried on
  the next RPC request, and the RPC path gets a structured RPC_UNKNOWN
  instead of an unhandled throw.
- Reject a service whose contract.name does not match the filename it is
  mounted under, naming both, instead of silently mounting under the
  filename while the typed client calls by contract name.
- Let ServiceError accept an explicit retryable and have the client pass the
  wire value through, instead of recomputing (and silently flipping) it from
  the error code alone.
- Document the gateway/X-Forwarded-* deployment requirement in the RPC
  README.

Each of the three code blockers has a new/extended test that was verified to
fail when its fix was reverted (rpc/test/integration.test.ts,
dev-server/test/rpc-services-loading.test.ts).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 20:36:31 +05:30
ClintchizandClaude Opus 5 e01915823a feat(rpc): transport, server, client, http, mounting, docs (Tasks 5-11)
Brings the uncommitted body of work under version control so it cannot be
lost. Gates are green: 152 tests pass across rpc/router/dev-server,
typecheck, lint, format and check:public-api all clean.

NOT YET REVIEWED. None of Tasks 5-11 has had an independent task review, and
Task 4's second fix round was never re-reviewed either.

Known gaps against the plan, recorded here rather than discovered later:
- packages/rpc/test/{transport,server,client}.test.ts are ABSENT. The plan
  required a test file for each. server.ts holds the fail-closed identity and
  permission checks and currently has no direct coverage at all.
- rpc-endpoint.test.ts has 3 tests where the plan specified 9. Missing:
  unknown service, non-POST, malformed body, non-rpc passthrough, and the
  isInternalCaller sweep. This is the task where a reachable
  /__wrnexus/rpc/* makes every permission check in the workspace bypassable.
- http.test.ts has 3 of 7; integration.test.ts 2 of 3;
  services-discovery.test.ts 1 of 4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 19:38:04 +05:30
ClintchizandClaude Opus 5 83c99cc3e5 fix(rpc): close identity-token fail-open and validation gaps
- importSubjectContext now rejects a non-string/empty selfApp before
  verifying. verifyJwt skips the audience check entirely when audience
  is undefined, so an unvalidated selfApp (the natural shape of
  currentAppName(): string | undefined) accepted every token from every
  app for every audience.
- exportSubjectContext now rejects a non-string/empty targetApp, so an
  array can no longer mint one token valid at multiple apps.
- Both directions now reject a present-but-non-string tenant id instead
  of silently dropping it (was: callee reads missing tenantId as
  global/unscoped -> cross-tenant exposure).
- importSubjectContext now requires exp to be present and independently
  bounds accepted token age via a new maxAge/ImportOptions.maxAgeSeconds
  (default 300s), so a caller cannot mint a long-lived token via a huge
  ttlSeconds and have it honoured indefinitely.
- SubjectContext.callerApp doc now states it is self-asserted (the
  signing secret is workspace-wide) and must never be an authz input.
- index.ts also exports the new ImportOptions type.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 14:26:14 +05:30
ClintchizandClaude Opus 5 2257ee871e feat(rpc): add the signed subject-context token
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 14:12:42 +05:30
Clintchiz e16903b286 feat(rpc): add defineService and the immutable procedure builder 2026-08-05 13:53:14 +05:30
ClintchizandClaude Opus 5 796b19d923 feat(rpc): add service errors and retryability classification
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-05 13:37:52 +05:30
Clintchiz e1fca3eddf feat(rpc): scaffold the package and shared contract types 2026-08-05 09:52:48 +05:30