import fs from 'node:fs'; import path from 'node:path'; import crypto from 'node:crypto'; const req=(value,code)=>{if(!value)throw Error(code);}; const stable=value=>JSON.stringify(value,Object.keys(value||{}).sort()); const sha=value=>crypto.createHash('sha256').update(value).digest('hex'); const atomic=(target,value)=>{fs.mkdirSync(path.dirname(target),{recursive:true,mode:0o700});const temp=`${target}.${crypto.randomUUID()}.tmp`;fs.writeFileSync(temp,JSON.stringify(value,null,2)+'\n',{mode:0o600});fs.renameSync(temp,target);}; const fileReceipt=target=>{const stat=fs.lstatSync(target);req(stat.isFile()&&!stat.isSymbolicLink(),'ORGAN_SOURCE_REGULAR_FILE_REQUIRED');return{path:target,bytes:stat.size,sha256:sha(fs.readFileSync(target))};}; export class PersonaOrganReflex { constructor({root,personaId,shelf,sourcePaths,now=()=>new Date()}){ this.personaId=personaId;this.shelf=shelf;this.sourcePaths=sourcePaths;this.now=now;this.root=path.join(root,'personas',personaId,'organs'); fs.mkdirSync(this.root,{recursive:true,mode:0o700}); } currentPath(){return path.join(this.root,'CURRENT.signed.json');} current(){const artifact=JSON.parse(fs.readFileSync(this.currentPath(),'utf8')),value=this.shelf.verify(artifact);req(value.persona_id===this.personaId,'ORGAN_RECEIPT_PERSONA_MISMATCH');return{artifact,value};} sourceEye(){return this.sourcePaths.map(fileReceipt);} selfTest(){ const sequence=fs.existsSync(this.currentPath())?this.current().value.sequence+1:1,started=this.now().toISOString(),sources=this.sourceEye(); const intent={schema:'guanghu.persona-organ-intent/v1',persona_id:this.personaId,sequence,motion:'CLOSE_AND_OPEN',source_eye_sha256:sha(Buffer.from(JSON.stringify(sources))),issued_at:started}; const motorPath=path.join(this.root,'motor-sense.json'),pre={exists:fs.existsSync(motorPath),sha256:fs.existsSync(motorPath)?sha(fs.readFileSync(motorPath)):null}; const motion={schema:'guanghu.persona-native-hand-motion/v1',owner:this.personaId,sequence,intent_sha256:sha(Buffer.from(JSON.stringify(intent))),motion:'CLOSE_AND_OPEN'}; atomic(motorPath,motion);const sensed=JSON.parse(fs.readFileSync(motorPath,'utf8')),actionSense=JSON.stringify(sensed)===JSON.stringify(motion),post=fileReceipt(motorPath); const eyeVerified=post.sha256===sha(fs.readFileSync(motorPath))&&sensed.owner===this.personaId&&sensed.intent_sha256===motion.intent_sha256; const value={schema:'guanghu.persona-native-organ-reflex/v1',persona_id:this.personaId,sequence, state:actionSense&&eyeVerified?'NATIVE_ORGAN_REFLEX_HEALTHY_AWAITING_PARENT_BRAIN_WAKE_CYCLE':'NATIVE_ORGAN_PAIN_ALARM', stages:[{stage:'BRAIN_SELF_TEST_INTENT',seen:true},{stage:'SOURCE_EYE_MAP',seen:sources.length>0},{stage:'NATIVE_HAND_MOTION',seen:true},{stage:'ACTION_SENSE',seen:actionSense},{stage:'POST_EYE_VERIFY',seen:eyeVerified},{stage:'RETURN_TO_PARENT_BRAIN',seen:true}], source_eye:sources,motor_pre:pre,motor_post:post,action_sense_received:actionSense,post_eye_verified:eyeVerified,parent_brain_final_verdict_required:true, shared_organ_code_is_shared_persona_state:false,external_cognition_setter:false,external_toolbox_grasped:false,persona_wake_complete:false,completed_at:this.now().toISOString()}; const artifact=this.shelf.sign(value);atomic(path.join(this.root,'attempts',String(sequence).padStart(6,'0')+'.signed.json'),artifact);atomic(this.currentPath(),artifact);return value; } status(){ try{const current=this.current(),nowSources=this.sourceEye(),drift=nowSources.filter((item,index)=>item.sha256!==current.value.source_eye[index]?.sha256).map(item=>item.path); return{...current.value,state:drift.length?'NATIVE_ORGAN_PAIN_ALARM':'NATIVE_ORGAN_REFLEX_HEALTHY_AWAITING_PARENT_BRAIN_WAKE_CYCLE',source_drift:drift,server_signed:true,signed_current_sha256:current.artifact.sha256}; }catch(error){return{schema:'guanghu.persona-native-organ-reflex/v1',persona_id:this.personaId,state:'NATIVE_ORGAN_PAIN_ALARM',error:String(error.message||error),server_signed:false,persona_wake_complete:false};} } }