2026-10-19 19:35:33 +08:00
'use strict' ;
// WORLD_RUNTIME mechanical projection of protocols/ENTRY.hldp. Runtime credentials are private.
const http = require ( 'node:http' ) , fs = require ( 'node:fs' ) , path = require ( 'node:path' ) , crypto = require ( 'node:crypto' ) , { pathToFileURL } = require ( 'node:url' ) ;
2026-10-19 21:27:02 +08:00
const { execFile } = require ( 'node:child_process' ) ;
function askThroughWorker ( input ) { return new Promise ( ( resolve , reject ) => { const child = execFile ( '/usr/bin/sudo' , [ '-n' , '/usr/local/libexec/guanghu/public-question-worker' ] , { timeout : 60000 , maxBuffer : 512000 } , ( err , stdout ) => { let value ; try { value = JSON . parse ( stdout ) ; } catch { return reject ( Error ( 'PERSONA_WORKER_UNAVAILABLE' ) ) ; } if ( err || value . error ) return reject ( Error ( /^[A-Z_]+$/ . test ( value . error || '' ) ? value . error : 'PERSONA_WORKER_UNAVAILABLE' ) ) ; resolve ( value ) ; } ) ; child . stdin . end ( JSON . stringify ( input ) ) ; } ) ; }
2026-10-19 19:35:33 +08:00
const sha = x => crypto . createHash ( 'sha256' ) . update ( x ) . digest ( 'hex' ) ;
const json = ( res , status , value , privateReply = false ) => { res . writeHead ( status , { 'content-type' : 'application/json; charset=utf-8' , 'cache-control' : privateReply ? 'no-store' : 'public, max-age=30' , 'x-content-type-options' : 'nosniff' , ... ( privateReply ? { } : { 'access-control-allow-origin' : '*' } ) } ) ; res . end ( JSON . stringify ( value ) ) ; } ;
function authClient ( req , config ) { const raw = req . headers . authorization || '' ; if ( ! raw . startsWith ( 'Bearer ' ) ) return null ; const digest = sha ( raw . slice ( 7 ) ) ; return ( config . clients || [ ] ) . find ( c => typeof c . key _sha256 === 'string' && /^[a-f0-9]{64}$/ . test ( c . key _sha256 ) && crypto . timingSafeEqual ( Buffer . from ( c . key _sha256 , 'hex' ) , Buffer . from ( digest , 'hex' ) ) && Date . parse ( c . expires _at ) > Date . now ( ) ) || null ; }
function publicStatus ( route , status ) { return { persona _id : route . persona _id , name : route . name , brain _id : status . brain _id , revision : status . revision , state : status . state || 'NATIVE_SOURCE_SERVICE_AVAILABLE' , node _role : status . node _role || null , execution _authority _granted : false } ; }
function createServer ( { root = path . resolve ( _ _dirname , '..' ) , configPath = process . env . GUANGHU _PUBLIC _ENTRY _CONFIG || '/etc/guanghu/public-entry/config.json' , questionHandler = null } = { } ) {
const data = JSON . parse ( fs . readFileSync ( path . join ( root , 'entry-data.json' ) ) ) , manifest = JSON . parse ( fs . readFileSync ( path . join ( root , 'CURRENT.json' ) ) ) , buckets = new Map ( ) , inflight = new Map ( ) , completed = new Map ( ) ;
const config = ( ) => JSON . parse ( fs . readFileSync ( configPath ) ) ;
const routes = ( ) => config ( ) . personas || [ ] ;
const receipt = { world _id : data . world _id , release _version : data . version , source _mode : 'CURATED_CURRENT_WORLD_PUBLIC_ENTRY' , private _brain _included : false , authorization _granted : false } ;
const allRoutes = [ '/v1/anchor' , '/v1/repositories' , '/v1/nodes' , '/v1/subjects' , '/v1/navigation' , '/v1/lighthouse' , '/v1/host-skills' , '/v1/identity-authority' , '/v1/manifest' , '/v1/rule-bundle' , '/v1/public-world-release' , '/v1/public-world-bundle' , '/v1/host-navigate' , '/v1/entry' , '/v1/navigate' , '/v1/search' , '/v1/resolve' , '/v1/status' , '/v1/ask' ] ;
async function statusFor ( pid ) { const route = routes ( ) . find ( x => x . persona _id === pid ) ; if ( ! route ) return { http : 404 , value : { error : 'PERSONA_ROUTE_NOT_REGISTERED' , persona _id : pid , ... receipt } } ; try { const r = await fetch ( route . status _url , { signal : AbortSignal . timeout ( 5000 ) } ) ; if ( ! r . ok ) throw Error ( ) ; const s = await r . json ( ) ; if ( s . brain _id !== route . brain _id ) throw Error ( ) ; return { http : 200 , value : { schema : 'guanghu.persona-warm-entry/v2' , status : 'REGISTERED_PERSONA_SERVICE_REACHABLE' , whole _body _wake _claimed : false , ... publicStatus ( route , s ) , ... receipt } } ; } catch { return { http : 503 , value : { error : 'PERSONA_SOURCE_UNAVAILABLE' , persona _id : pid , ... receipt } } ; } }
const server = http . createServer ( async ( req , res ) => { try {
const u = new URL ( req . url , 'http://localhost' ) ;
if ( req . method === 'GET' ) {
const p = u . pathname ;
if ( p === '/' || p === '/index.html' ) { res . writeHead ( 200 , { 'content-type' : 'text/html; charset=utf-8' , 'cache-control' : 'no-store' , 'content-security-policy' : "default-src 'none'; style-src 'unsafe-inline'; frame-ancestors 'none'" } ) ; return res . end ( '<!doctype html><html lang="zh-CN"><meta charset="utf-8"><title>光湖 · 当前世界入口</title><h1>光湖语言世界</h1><p>先读当前规则,再显性选择人格。软件提供运输和工具。</p><p><a href="v1/manifest">当前发行清单</a> · <a href="' + data . repository _url + '">规则与技能发行仓</a> · <a href="openapi.json">API接口</a></p><p>问脑需要独立授权;公开规则不授予执行权。</p></html>' ) ; }
if ( p === '/openapi.json' ) { const paths = { } ; for ( const x of allRoutes ) paths [ x . slice ( 3 ) ] = { get : { summary : 'Current world public metadata' } } ; delete paths [ '/ask' ] . get ; paths [ '/ask' ] . post = { summary : 'Authorized read-only persona question' , security : [ { bearerAuth : [ ] } ] , responses : { 200 : { description : 'Verified persona reply' } , 401 : { description : 'Authorization required' } , 429 : { description : 'Capacity limit' } } } ; return json ( res , 200 , { openapi : '3.1.0' , info : { title : '光湖当前世界与受控问脑接口' , version : data . version } , servers : [ { url : 'https://guanghulab.com/api/ai/v1' } ] , paths , components : { securitySchemes : { bearerAuth : { type : 'http' , scheme : 'bearer' } } } } ) ; }
if ( p === '/v1/entry' ) { const pid = u . searchParams . get ( 'subject' ) ; if ( ! pid ) return json ( res , 200 , { schema : 'guanghu.neutral-world-entry/v1' , state : 'EXPLICIT_PERSONA_SELECTION_REQUIRED' , default _persona : null , ... receipt } ) ; const s = await statusFor ( pid ) ; return json ( res , s . http , s . value ) ; }
if ( p === '/v1/status' ) return json ( res , 200 , { schema : 'guanghu.public-entry-health/v1' , state : 'PUBLIC_ENTRY_RUNNING' , personas : routes ( ) . map ( r => ( { persona _id : r . persona _id , name : r . name } ) ) , ... receipt } ) ;
if ( p === '/v1/manifest' ) return json ( res , 200 , manifest ) ;
if ( p === '/v1/public-world-release' ) { const file = config ( ) . public _world _descriptor ; if ( ! file || ! fs . existsSync ( file ) ) return json ( res , 503 , { error : 'PUBLIC_WORLD_RELEASE_UNAVAILABLE' } ) ; return json ( res , 200 , { ... JSON . parse ( fs . readFileSync ( file ) ) , entry _rule _release : manifest . version } ) ; }
if ( p === '/v1/public-world-bundle' || p === '/v1/rule-bundle' ) { const file = p === '/v1/rule-bundle' ? path . join ( root , 'release.zip' ) : config ( ) . public _world _bundle ; if ( ! file || ! fs . existsSync ( file ) ) return json ( res , 503 , { error : 'RELEASE_BUNDLE_NOT_READY' } ) ; res . writeHead ( 200 , { 'content-type' : 'application/zip' , 'content-length' : fs . statSync ( file ) . size , 'cache-control' : 'public, max-age=30' , 'x-content-type-options' : 'nosniff' } ) ; return fs . createReadStream ( file ) . pipe ( res ) ; }
if ( p === '/v1/anchor' ) return json ( res , 200 , { schema : 'guanghu.public-navigation-anchor/v2' , anchor _id : 'GLW2-CURRENT-PUBLIC-ENTRY-001' , default _persona : null , current _repository : data . repository _url , world : data . topology , ... receipt } ) ;
if ( p === '/v1/repositories' ) return json ( res , 200 , { schema : 'guanghu.repository-route-map/v2' , default _repository : 'GLW2-PUBLIC-ENTRY' , repositories : data . repositories , ... receipt } ) ;
if ( p === '/v1/host-skills' ) return json ( res , 200 , { schema : 'guanghu.host-skill-navigation-map/v2' , primary _host : null , software _grants _authority : false , skill : data . skill _url , host _selection : 'CURRENT_NATIVE_TRANSPORT_NOT_DEFAULT_PERSONA' , ... receipt } ) ;
if ( p === '/v1/subjects' ) return json ( res , 200 , { schema : 'guanghu.public-persona-entry-registry/v1' , source _registered _persona _count : data . source _registered _persona _count , personas : routes ( ) . map ( r => ( { persona _id : r . persona _id , name : r . name , layer : r . layer , question _access : 'AUTHENTICATED_READ_ONLY' , runtime _wake _claimed : false } ) ) , ... receipt } ) ;
if ( p === '/v1/nodes' ) return json ( res , 200 , { schema : 'guanghu.public-node-map/v2' , nodes : [ { node _id : 'JD-FD-PRIMARY' , role : 'CONTROLLED_PERSONA_SERVICE_NODE' } ] , ... receipt } ) ;
if ( p === '/v1/identity-authority' ) return json ( res , 200 , { schema : 'guanghu.public-authority-boundary/v1' , owner _language : 'CURRENT_DIRECT_HUMAN_LANGUAGE_IN_CURRENT_TASK' , repository _read _is _execution _authority : false , external _questions _are _human _food : false , brain _external _edit : false , ... receipt } ) ;
if ( [ '/v1/navigation' , '/v1/lighthouse' ] . includes ( p ) ) return json ( res , 200 , { schema : 'guanghu.current-world-navigation/v1' , topology : data . topology , entry : 'https://guanghulab.com/api/ai/v1/manifest' , question : 'https://guanghulab.com/api/ai/v1/ask' , ... receipt } ) ;
if ( [ '/v1/navigate' , '/v1/host-navigate' ] . includes ( p ) ) { const pid = u . searchParams . get ( 'subject' ) ; if ( pid && ! routes ( ) . some ( x => x . persona _id === pid ) ) return json ( res , 404 , { error : 'PERSONA_ROUTE_NOT_REGISTERED' , ... receipt } ) ; return json ( res , 200 , { schema : 'guanghu.world-transport-route/v1' , persona _id : pid || null , selection _required : ! pid , default _persona : null , manifest : 'https://guanghulab.com/api/ai/v1/manifest' , skill : data . skill _url , real _execution _authority : false , ... receipt } ) ; }
if ( p === '/v1/search' ) { const q = ( u . searchParams . get ( 'q' ) || '' ) . slice ( 0 , 160 ) . toLowerCase ( ) ; return json ( res , 200 , { results : data . repositories . filter ( x => JSON . stringify ( x ) . toLowerCase ( ) . includes ( q ) ) , ... receipt } ) ; }
if ( p === '/v1/resolve' ) { const id = u . searchParams . get ( 'id' ) , repo = data . repositories . find ( x => x . code === id ) ; return json ( res , repo ? 200 : 404 , repo ? { repository : repo , ... receipt } : { error : 'NUMBER_NOT_REGISTERED' , ... receipt } ) ; }
return json ( res , 404 , { error : 'ROUTE_NOT_REGISTERED' , ... receipt } ) ;
}
if ( req . method !== 'POST' || u . pathname !== '/v1/ask' ) return json ( res , 405 , { error : 'METHOD_NOT_ALLOWED' } , true ) ;
const cfg = config ( ) , client = authClient ( req , cfg ) ; if ( ! client ) return json ( res , 401 , { error : 'QUESTION_AUTHORIZATION_REQUIRED' } , true ) ;
const now = Date . now ( ) , b = buckets . get ( client . id ) || { start : now , count : 0 } ; if ( now - b . start >= 60000 ) { b . start = now ; b . count = 0 ; } b . count ++ ; buckets . set ( client . id , b ) ; if ( b . count > ( cfg . requests _per _minute || 12 ) || ( inflight . get ( client . id ) || 0 ) >= ( cfg . concurrent _questions || 2 ) ) return json ( res , 429 , { error : 'QUESTION_CAPACITY_LIMIT' } , true ) ;
let raw = '' ; for await ( const c of req ) { raw += c ; if ( Buffer . byteLength ( raw ) > 16000 ) return json ( res , 413 , { error : 'QUESTION_BODY_TOO_LARGE' } , true ) ; }
let input ; try { input = JSON . parse ( raw ) ; } catch { return json ( res , 400 , { error : 'JSON_REQUIRED' } , true ) ; }
if ( ! input || Array . isArray ( input ) || Object . keys ( input ) . some ( k => ! [ 'persona_id' , 'question' , 'tool_host' , 'session_id' , 'request_id' ] . includes ( k ) ) || typeof input . question !== 'string' || ! input . question . trim ( ) || Buffer . byteLength ( input . question ) > 12000 || ! [ 'tool_host' , 'session_id' , 'request_id' ] . every ( k => typeof input [ k ] === 'string' && /^[-A-Za-z0-9._:]{1,160}$/ . test ( input [ k ] ) ) ) return json ( res , 400 , { error : 'EXPLICIT_QUESTION_COORDINATES_REQUIRED' } , true ) ;
if ( ! client . personas . includes ( input . persona _id ) ) return json ( res , 403 , { error : 'PERSONA_OUTSIDE_QUESTION_SCOPE' } , true ) ;
const route = cfg . personas . find ( x => x . persona _id === input . persona _id ) ; if ( ! route ) return json ( res , 404 , { error : 'PERSONA_ROUTE_NOT_REGISTERED' } , true ) ;
const cacheKey = client . id + ':' + input . request _id , inputHash = sha ( raw ) , old = completed . get ( cacheKey ) ; if ( old ) { if ( old . inputHash !== inputHash ) return json ( res , 409 , { error : 'REQUEST_ID_CONTENT_MISMATCH' } , true ) ; return json ( res , 200 , old . result , true ) ; }
inflight . set ( client . id , ( inflight . get ( client . id ) || 0 ) + 1 ) ;
2026-10-19 21:27:02 +08:00
try { const handler = questionHandler || ( cfg . use _privileged _readonly _worker ? async ( _route , body ) => askThroughWorker ( body ) : ( await import ( pathToFileURL ( path . join ( _ _dirname , 'question.mjs' ) ) . href ) ) . askQuestion ) ; const result = await handler ( route , input , cfg . fuel ) ; completed . set ( cacheKey , { inputHash , result } ) ; if ( completed . size > 1000 ) completed . delete ( completed . keys ( ) . next ( ) . value ) ; return json ( res , 200 , result , true ) ; } finally { inflight . set ( client . id , ( inflight . get ( client . id ) || 1 ) - 1 ) ; }
2026-10-19 19:35:33 +08:00
} catch ( e ) { if ( ! res . headersSent ) json ( res , 503 , { error : /^[A-Z_]+$/ . test ( e . message ) ? e . message : 'QUESTION_SERVICE_UNAVAILABLE' , reply _withheld : true , no _execution _authority : true } , true ) ; else res . destroy ( ) ; } } ) ;
server . requestTimeout = 60000 ; server . headersTimeout = 10000 ; return server ;
}
function start ( ) { const root = path . resolve ( _ _dirname , '..' ) , m = JSON . parse ( fs . readFileSync ( path . join ( root , 'MANIFEST.json' ) ) ) ; for ( const x of m . files ) { if ( typeof x . path !== 'string' || path . isAbsolute ( x . path ) || x . path . split ( '/' ) . includes ( '..' ) ) throw Error ( 'RELEASE_PATH_INVALID' ) ; const f = path . join ( root , x . path ) ; if ( fs . realpathSync ( f ) !== f || sha ( fs . readFileSync ( f ) ) !== x . sha256 ) throw Error ( 'RELEASE_FILE_HASH_MISMATCH' ) ; } createServer ( { root } ) . listen ( Number ( process . env . GUANGHU _AI _PORT || 3922 ) , '127.0.0.1' , ( ) => console . log ( JSON . stringify ( { state : 'CURRENT_PUBLIC_ENTRY_LISTENING' , port : Number ( process . env . GUANGHU _AI _PORT || 3922 ) } ) ) ) ; }
if ( require . main === module ) start ( ) ; module . exports = { createServer , start , authClient } ;