@@ -59,6 +59,67 @@ export class HttpDispatcher {
5959 } ;
6060 }
6161
62+ /**
63+ * 501 Not Implemented – route is declared but handler is a stub or missing.
64+ */
65+ private notImplemented ( route : string , service ?: string ) {
66+ return {
67+ status : 501 ,
68+ body : {
69+ success : false ,
70+ error : {
71+ code : 501 ,
72+ message : `Not Implemented: ${ route } ` ,
73+ type : 'NOT_IMPLEMENTED' as const ,
74+ route,
75+ service,
76+ hint : service
77+ ? `The "${ service } " service route is declared but has no handler. Install or implement the handler.`
78+ : 'This endpoint is declared but not yet implemented.' ,
79+ } ,
80+ } ,
81+ } ;
82+ }
83+
84+ /**
85+ * 503 Service Unavailable – service exists in the route table but is currently down.
86+ */
87+ private serviceUnavailable ( route : string , service : string ) {
88+ return {
89+ status : 503 ,
90+ body : {
91+ success : false ,
92+ error : {
93+ code : 503 ,
94+ message : `Service Unavailable: ${ service } ` ,
95+ type : 'SERVICE_UNAVAILABLE' as const ,
96+ route,
97+ service,
98+ hint : `The "${ service } " service is registered but currently unavailable. It may need to be started or a plugin installed.` ,
99+ } ,
100+ } ,
101+ } ;
102+ }
103+
104+ /**
105+ * 404 Route Not Found — no route is registered for this path.
106+ */
107+ private routeNotFound ( route : string ) {
108+ return {
109+ status : 404 ,
110+ body : {
111+ success : false ,
112+ error : {
113+ code : 404 ,
114+ message : `Route Not Found: ${ route } ` ,
115+ type : 'ROUTE_NOT_FOUND' as const ,
116+ route,
117+ hint : 'No route is registered for this path. Check the API discovery endpoint for available routes.' ,
118+ } ,
119+ } ,
120+ } ;
121+ }
122+
62123 private ensureBroker ( ) {
63124 if ( ! this . kernel . broker ) {
64125 throw { statusCode : 500 , message : 'Kernel Broker not available' } ;
@@ -133,11 +194,14 @@ export class HttpDispatcher {
133194 } ;
134195
135196 // Build per-service status map
197+ // handlerReady: true means the dispatcher has a real handler for this route.
198+ // handlerReady: false with status 'registered' means the route is in the table
199+ // but the handler may not exist or be a stub.
136200 const svcAvailable = ( route ?: string , provider ?: string ) => ( {
137- enabled : true , status : 'available' as const , route, provider,
201+ enabled : true , status : 'available' as const , handlerReady : true , route, provider,
138202 } ) ;
139203 const svcUnavailable = ( name : string ) => ( {
140- enabled : false , status : 'unavailable' as const ,
204+ enabled : false , status : 'unavailable' as const , handlerReady : false ,
141205 message : `Install a ${ name } plugin to enable` ,
142206 } ) ;
143207
@@ -174,7 +238,7 @@ export class HttpDispatcher {
174238 } ,
175239 services : {
176240 // Kernel-provided (always available via protocol implementation)
177- metadata : { enabled : true , status : 'degraded' as const , route : routes . metadata , provider : 'kernel' , message : 'In-memory registry; DB persistence pending' } ,
241+ metadata : { enabled : true , status : 'degraded' as const , handlerReady : true , route : routes . metadata , provider : 'kernel' , message : 'In-memory registry; DB persistence pending' } ,
178242 data : svcAvailable ( routes . data , 'kernel' ) ,
179243 // Plugin-provided — only available when a plugin registers the service
180244 auth : hasAuth ? svcAvailable ( routes . auth ) : svcUnavailable ( 'auth' ) ,
@@ -1207,6 +1271,19 @@ export class HttpDispatcher {
12071271 } ;
12081272 }
12091273
1274+ // 0b. Health Endpoint (GET /health)
1275+ if ( cleanPath === '/health' && method === 'GET' ) {
1276+ return {
1277+ handled : true ,
1278+ response : this . success ( {
1279+ status : 'ok' ,
1280+ timestamp : new Date ( ) . toISOString ( ) ,
1281+ version : '1.0.0' ,
1282+ uptime : typeof process !== 'undefined' ? process . uptime ( ) : undefined ,
1283+ } ) ,
1284+ } ;
1285+ }
1286+
12101287 // 1. System Protocols (Prefix-based)
12111288 if ( cleanPath . startsWith ( '/auth' ) ) {
12121289 return this . handleAuth ( cleanPath . substring ( 5 ) , method , body , context ) ;
@@ -1265,8 +1342,11 @@ export class HttpDispatcher {
12651342 const result = await this . handleApiEndpoint ( cleanPath , method , body , query , context ) ;
12661343 if ( result . handled ) return result ;
12671344
1268- // 3. Fallback (404)
1269- return { handled : false } ;
1345+ // 3. Fallback — return semantic 404 with diagnostic info
1346+ return {
1347+ handled : true ,
1348+ response : this . routeNotFound ( cleanPath ) ,
1349+ } ;
12701350 }
12711351
12721352 /**
0 commit comments