feat: attribute registry calls made through host Fastify routes - #166
Merged
Merged
Conversation
In development, tau-js now observes registry-backed work performed through ordinary Fastify route handlers without taking ownership of those routes. A handler that calls the service registry through callServiceMethod with no explicit recorder is correlated to a host-observed episode carrying the route method and path, the registry calls made in it and the response outcome. The seam is Fastify's own documented request-handler tracing channel with a bound AsyncLocalStorage; nothing is added to the caller's instance and nothing runs in production. Recorder events gain an explicit episode kind, a status on failed and a host arm on sent; observations schema moves to version 2 and the mcp reader gates episodes as a paired read. taujs_who_calls_service reports host-observed callers separately from declared and observed edges, and taujs_explain_route can answer for an observed host path from a live boot, saying "no observation" rather than implying no request occurred.
Three correctness fixes on top of b4bc618, each with regression cells. taujs_explain_route now gates on discovery.mode === 'active' rather than the presence of devJson.bootId: a stale boot deliberately retains its own devJson, so a crashed or expired boot could otherwise still answer from its episodes. CreateServer no longer releases host attribution by re-deriving the registry from opts.serviceRegistry, which is undefined when the caller supplied none. SSRServer now hands back an idempotent disposer closure that already captures the exact registry and introspection it acquired with, so a boot that fails after acquiring never leaks the binding. The paired episode read no longer fails open: a missing or unreadable observations document now refuses episodes.ndjson explicitly, rather than letting an undefined probed version pass through unguarded. Fixtures that wrote episodes without their paired observations document are corrected. taujs_explain_route preserves a reader refusal instead of reporting it as "no observation".
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Host-route attribution
In development, τjs now observes registry-backed work performed through ordinary Fastify route handlers, without taking ownership of those routes. A handler that calls the service registry through
callServiceMethodwith no explicit recorder is correlated to a host-observed episode carrying the route's method and path, the registry calls made in it, and the response outcome.The seam is Fastify's documented
fastify.request.handlertracing channel with a boundAsyncLocalStorage. Nothing is added to the caller's Fastify instance, no application handler changes, and nothing binds outside development.@taujs/server (minor)
EpisodeRecorder:routeMatchedgains a requiredkind: 'page' | 'host'and an optionalmethod;sentgains a host arm without a render mode;failedcarries the responsestatuswith an optional error.appId: nulland identityhost:<method> <path>; page identities are unchanged.@taujs/mcp (minor)
episodes.ndjsonis a paired read withobservations.jsonand fails closed when the pairing is missing, unreadable or mismatched.taujs_who_calls_servicereportshostObservedcallers separately fromdeclaredandobserved.taujs_explain_routeanswers for an observed host path from a live boot only, preserves a reader refusal, and says "no observation" rather than implying no request occurred.Limits, stated
Not route discovery, not API ownership, not complete request monitoring. Validation failures before the first registry call, unexercised routes, calls from hooks, and calls outside the request's async continuation leave no episode. "No observation" means unknown.
Verification
Full workspace gates green (build, test, typecheck, check-format, check-exports).