@devflow-tools/cli 0.18.10 → 0.18.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,17 @@
1
- import {getLocalApiKey,getDevFlowStateRoot,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {existsSync as existsSync$1,readFileSync as readFileSync$1,rmSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1}from'fs';import {join as join$1}from'path';import {randomUUID,createHash as createHash$1}from'crypto';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import'@devflow-tools/memory-engine';import {request}from'node:http';import {mkdirSync,existsSync,writeFileSync,renameSync,unlinkSync,readFileSync,openSync,constants,fstatSync,closeSync,appendFileSync,lstatSync,readSync}from'node:fs';import {join,resolve}from'node:path';import {emitSemanticControlLog,rotateDiagnosticLogFile,SemanticRuntimeEventProjector}from'@devflow-tools/telemetry';import {createHash}from'node:crypto';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';function _(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(n){return getProjectStateDir(_(n))}function U(n){return Buffer.from(n,"utf8").toString("base64url")}function we(n,e,t){let o=e?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash$1("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function V(n){return `${n}:legacy-journal`}var I=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(w(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let o=this.get(t);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,o){let r=this.registerSession(e);return (!r.executionId||r.skillName!==t)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=t,r.requiredMcpTools=[...new Set(o)],r.lastActivityAt=Date.now(),this.persist(r),r}bindTaskIdentity(e,t){let o=this.registerSession(e);return o.activeTurnId=t.turnId,o.activeRequestId=t.requestId,o.intentArtifactHash=t.intentArtifactHash,o.lastActivityAt=Date.now(),this.persist(o),o}get(e){let t=e.trim();if(!t)return null;let o=this.sessions.get(t);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(t);if(!existsSync$1(r))return null;try{let i=JSON.parse(readFileSync$1(r,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=B(i.evidenceObligations),i.evidenceDegradations=J(i.evidenceDegradations),i.evidenceOutcomes=W(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let o=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),o}addEvidenceObligation(e,t,o=Date.now(),r){let i=this.registerSession(e),a=(r?void 0:i.evidenceObligations.find(u=>u.contractId===t.id))?.obligationId??we(t.id,r,o);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:o,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(u=>u.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,o,r,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(d=>d.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(d=>d.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let u=s.evidenceObligations.find(d=>d.obligationId===t);return u?structuredClone(u):null}resolveEvidenceObligation(e,t){let o=this.get(e);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===t);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}resolveDegradedEvidence(e,t){let o=this.get(e),r=o?.evidenceDegradations.find(s=>s.obligationId===t);if(!o||!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve-degraded\0${t}\0${i}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(e,t,o,r=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:r,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${U(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",U(e))}appendEvidenceEvent(e,t,o){let r=this.evidenceJournalDir(e);mkdirSync$1(r,{recursive:true,mode:448});let i=createHash$1("sha256").update(o).digest("hex"),s=join$1(r,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=B(e.evidenceObligations),e.evidenceDegradations=J(e.evidenceDegradations),e.evidenceOutcomes=W(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let o;try{o=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=Se(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||G(i.kind)-G(s.kind));for(let i of r)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let o=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(o)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let r=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!r||o||r.correctionFingerprint===t.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=t.at,r.correctionFingerprint=t.fingerprint,r.violations=t.violations;return}let i=r?.attempt??o?.attempt??0;if(t.kind==="resolve"&&o?.status==="degraded")e.evidenceOutcomes=e.evidenceOutcomes.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations=e.evidenceDegradations.filter(s=>s.obligationId!==t.obligationId);else if(o)return;t.kind==="degrade"?(e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i,contract:r?.contract})):e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}});}persist(e){mkdirSync$1(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),o=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(o,JSON.stringify(e),{mode:384}),renameSync$1(o,t);}};function B(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!X(t.contract))return [];let o=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:V(t.contractId),r=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function J(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function W(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function Se(n){if(!n||typeof n!="object")return null;let e=n,t=e.kind;if(t!=="add"&&t!=="correction"&&t!=="resolve"&&t!=="degrade"||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let r={obligationId:typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:V(e.contractId),contractId:e.contractId,at:e.at};if(t==="add")return X(e.contract)?{kind:t,...r,contract:e.contract}:null;if(t==="correction"){let i=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(e.violations)&&e.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:t,...r,fingerprint:i,violations:e.violations}:null}return t==="resolve"?{kind:t,...r}:typeof e.reason=="string"&&e.reason.length<=240?{kind:t,...r,reason:e.reason}:null}function G(n){return n==="add"?0:n==="correction"?1:2}function X(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,o=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function T(n,e,t){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{o.close();}}catch{}}var Pe=getLocalApiKey(),D=join(getDevFlowStateRoot(),"errors");async function k(n,e,t={}){let o=t.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??Fe();if(!o)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let r=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let u;for(let l=0;l<=s;l+=1)try{return await qe(o,n,e,r),a&&registerRuntimeHttpSuccess(o,n).transitioned&&T("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(m){u=m instanceof Error?m:new Error(String(m)),l<s&&await Ne(Math.min(100*2**l,1e3));}if(!u)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return Y(n,u),{delivered:false,suppressed:false,fallbackReason:u.message};let d=registerRuntimeHttpFailure(o,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(Y(n,u),T("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"open",failures:d.state.failures,openUntil:d.state.openUntil,fallbackReason:d.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:d.state.fallbackReason}}function Fe(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function qe(n,e,t,o){return new Promise((r,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,u=l=>{c||(c=true,l?i(l):r());},d=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Pe,"Content-Length":Buffer.byteLength(s)},timeout:o},l=>{l.on("error",u),l.on("end",()=>{let m=l.statusCode??0;u(m>=200&&m<300?void 0:new Error(`HTTP ${m}`));}),l.resume();});d.on("error",u),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${o}ms`))),d.write(s),d.end();})}function Y(n,e){try{existsSync(D)||mkdirSync(D,{recursive:!0});let t=join(D,"http-errors.log"),o=`${new Date().toISOString()} | ${n} | ${e.message}
2
- `;rotateDiagnosticLogFile({path:t,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(t,o);}catch{}}function Ne(n){return new Promise(e=>setTimeout(e,n))}function te(n,e){let t=Be(n);mkdirSync(t,{recursive:true,mode:448});let o=join(t,`${e.receiptId}.json`);if(existsSync(o))return e.receiptId;let r=`${o}.${process.pid}.tmp`;writeFileSync(r,JSON.stringify(e),{mode:384});try{renameSync(r,o);}catch(i){try{unlinkSync(r);}catch{}if(!existsSync(o))throw i}return e.receiptId}function Be(n){return join(w(n),"session-finalize-pending")}var p=emitSemanticControlLog;function O(n){let{projectRoot:e,...t}=n;try{return new M(e).dispatchBoundary(t).snapshot??null}catch(o){return p({event:"hook.runtime.degraded",identity:{projectRoot:e,sessionId:n.sessionId,...n.turnId?{turnId:n.turnId}:{},...n.requestId?{requestId:n.requestId}:{},...n.executionId?{executionId:n.executionId}:{}},level:"error",timestamp:Date.now(),data:{stage:n.kind,reason:o instanceof Error?o.message:String(o),tool:n.producer}}),null}}var M=class{constructor(e){this.projectRoot=e;}dispatchBoundary(e){let t=Xe(e.kind,e.payload??{});if(!t)return {handled:false};let o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let r=Ve(o,{projectRoot:this.projectRoot,sessionId:e.sessionId,...e.turnId?{turnId:e.turnId}:{},...e.requestId?{requestId:e.requestId}:{},...e.executionId?{executionId:e.executionId}:{}});return r?{handled:!0,snapshot:new TaskKernel(new TaskEventStore(o),new SemanticRuntimeEventProjector).dispatch({definition:r.definition,kind:t.kind,payload:t.payload,idempotencyKey:`host:${r.definition.definitionHash}:${e.dedupeKey}`,producer:e.producer}).snapshot}:{handled:!1}}finally{o.close();}}};function Ve(n,e){let t=e.executionId?n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId):null,o=e.turnId??t?.canonicalAction?.binding.turnId,r=e.requestId??t?.requestId;if(!o&&!r)return null;let i=n.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId).find(c=>o?c.turnId===o:c.requestId===r);if(!i)return null;let s=n.getTaskAggregateSnapshot(e.projectRoot,e.sessionId,i.turnId,i.version);if(!s)return null;let a=n.getTaskDefinitionV2(s.taskDefinitionHash);return !a||a.revision!==i.version?null:{definition:a,snapshot:s}}function Xe(n,e){switch(n){case "action.lease.issued":return {kind:"action_lease_issued",payload:e};case "action.succeeded":return {kind:"action_completed",payload:e};case "action.failed":return {kind:"action_failed",payload:e};case "verification.succeeded":return {kind:"verification_completed",payload:e};case "verification.failed":return {kind:"verification_failed",payload:e};case "memory.committed":return {kind:"memory_episode_persisted",payload:e};case "memory.skipped":return {kind:"memory_decision_completed",payload:e};case "memory.pending":return {kind:"memory_extraction_queued",payload:e};case "memory.failed":return {kind:"memory_extraction_failed",payload:e};case "durable_work.owned":return {kind:"durable_work_leased",payload:{...e,fencingToken:Number.isSafeInteger(e.fencingToken)?e.fencingToken:0}};case "durable_work.completed":return {kind:"durable_work_completed",payload:e};case "durable_work.dead_lettered":return {kind:"durable_work_dead_lettered",payload:e};default:return null}}var nt=512*1024,ot=500;var rt=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function ie(n){let e=n.runtimeStore??new I(n.projectRoot),t=e.listEvidenceObligations(n.sessionId);if(t.length===0)return it(n,e),null;let o=$(n.transcriptPath,t);if(!o.answer){let s=o.degradationReason??"transcript_answer_unavailable";for(let a of t)e.degradeEvidenceObligation(n.sessionId,a.obligationId,s);return null}let r=o.fingerprint;if(!r){for(let s of t)e.degradeEvidenceObligation(n.sessionId,s.obligationId,"transcript_identity_unavailable");return null}let i=[];for(let s of t){let a=se(o.answer,[s]);if(a.length===0){e.resolveEvidenceObligation(n.sessionId,s.obligationId),x(n,s,"satisfied",r);continue}if(!s.correctionFingerprint){e.markEvidenceCorrection(n.sessionId,s.obligationId,a,r),i.push({obligation:s,violations:a}),x(n,s,"correction_requested",r,a);continue}if(s.correctionFingerprint===r){i.push({obligation:s,violations:a});continue}e.degradeEvidenceObligation(n.sessionId,s.obligationId,"evidence_contract_unresolved"),x(n,s,"degraded",r,a);}return i.length===0?null:st(i)}function it(n,e){let t=(e.get(n.sessionId)?.evidenceDegradations??[]).filter(i=>i.contract).slice(-8);if(t.length===0)return;let o=t.map(i=>({obligationId:i.obligationId,contractId:i.contractId,contract:i.contract,promptedAt:i.degradedAt,attempt:i.attempt,correctionRequested:true,violations:[]})),r=$(n.transcriptPath,o);if(!(!r.answer||!r.fingerprint))for(let i of o)se(r.answer,[i]).length>0||e.resolveDegradedEvidence(n.sessionId,i.obligationId)&&x(n,i,"satisfied",r.fingerprint);}function x(n,e,t,o,r=[]){t!=="correction_requested"&&O({projectRoot:n.projectRoot,sessionId:n.sessionId,kind:t==="satisfied"?"verification.succeeded":"verification.failed",payload:{receiptId:e.obligationId,reasonCode:t==="satisfied"?"performance_evidence_satisfied":"performance_evidence_unresolved"},dedupeKey:`${e.obligationId}:${t}:${e.attempt}`,producer:"devflow-evidence-contract"}),p({event:"verification.completed",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId},level:t==="satisfied"?"info":t==="degraded"?"error":"warn",timestamp:Date.now(),data:{stage:"performance_evidence_transition",status:t,contractId:e.contractId,obligationId:e.obligationId,attempt:e.attempt,answerFingerprint:o,violations:r,supersedesDegradation:t==="satisfied"&&e.attempt>0}});}function st(n){let e=[...new Set(n.flatMap(o=>o.violations))],t=[...new Map(n.map(o=>[o.obligation.contractId,o.obligation.contract.canonicalReport])).values()];return {decision:"block",reason:["DevFlow evidence contract violation. Correct the final performance answer once before stopping.",`Violations: ${e.join("; ")}`,"Use this canonical report (you may add clearly labeled hypotheses or runtime verification steps, but no unsupported measured claims):",t.join(`
1
+ import {getLocalApiKey,getDevFlowStateRoot,acquireRuntimeHttpCircuit,registerRuntimeHttpSuccess,registerRuntimeHttpFailure,getProjectStateDir,readRuntimeState}from'@devflow-tools/sdk';import {existsSync as existsSync$1,readFileSync as readFileSync$1,rmSync,mkdirSync as mkdirSync$1,writeFileSync as writeFileSync$1,linkSync,readdirSync,renameSync as renameSync$1}from'fs';import {join as join$1}from'path';import {randomUUID,createHash as createHash$1}from'crypto';import {openGlobalDevFlowDatabase}from'@devflow-tools/database';import'@devflow-tools/memory-engine';import {request}from'node:http';import {existsSync,mkdirSync,writeFileSync,renameSync,unlinkSync,readFileSync,openSync,constants,fstatSync,closeSync,appendFileSync,lstatSync,readSync}from'node:fs';import {join,resolve}from'node:path';import {emitSemanticControlLog,rotateDiagnosticLogFile,SemanticRuntimeEventProjector}from'@devflow-tools/telemetry';import {createHash}from'node:crypto';import {TaskKernel,TaskEventStore}from'@devflow-tools/task-runtime';import {DatabaseSync}from'node:sqlite';function _(n){return n??process.env.CLAUDE_PROJECT_DIR??process.cwd()}function w(n){return getProjectStateDir(_(n))}function z(n){return Buffer.from(n,"utf8").toString("base64url")}function Se(n,e,t){let o=e?.trim();if(o){let r=/^[a-zA-Z0-9:._-]{1,192}$/.test(o)?o:`tool-${createHash$1("sha256").update(o.slice(0,1024)).digest("hex").slice(0,32)}`;return `${n}:${r}`}return `${n}:legacy-${t}-${randomUUID().slice(0,8)}`}function V(n){return `${n}:legacy-journal`}var I=class{constructor(e){this.projectRoot=e;this.sessions=new Map;this.sessionsDir=join$1(w(e),"hook-sessions");}registerSession(e){let t=e.trim();if(!t)throw new Error("session_id_required");let o=this.get(t);if(o)return o.lastActivityAt=Date.now(),this.persist(o),o;let r=Date.now(),i={sessionId:t,projectRoot:this.projectRoot,requiredMcpTools:[],evidenceObligations:[],evidenceDegradations:[],evidenceOutcomes:[],startedAt:r,lastActivityAt:r};return this.sessions.set(t,i),this.persist(i),i}startExecution(e,t,o){let r=this.registerSession(e);return (!r.executionId||r.skillName!==t)&&(r.executionId=`exec_${Date.now()}_${randomUUID().slice(0,8)}`),r.skillName=t,r.requiredMcpTools=[...new Set(o)],r.lastActivityAt=Date.now(),this.persist(r),r}bindTaskIdentity(e,t){let o=this.registerSession(e);return o.activeTurnId=t.turnId,o.activeRequestId=t.requestId,o.intentArtifactHash=t.intentArtifactHash,o.lastActivityAt=Date.now(),this.persist(o),o}get(e){let t=e.trim();if(!t)return null;let o=this.sessions.get(t);if(o)return this.replayEvidenceJournal(o),o;let r=this.snapshotPath(t);if(!existsSync$1(r))return null;try{let i=JSON.parse(readFileSync$1(r,"utf8"));return i.sessionId!==t||i.projectRoot!==this.projectRoot?null:(i.requiredMcpTools=Array.isArray(i.requiredMcpTools)?i.requiredMcpTools:[],i.evidenceObligations=B(i.evidenceObligations),i.evidenceDegradations=J(i.evidenceDegradations),i.evidenceOutcomes=W(i.evidenceOutcomes),this.replayEvidenceJournal(i),this.sessions.set(t,i),i)}catch{return null}}completeExecution(e){let t=this.get(e);if(!t)return null;let o=structuredClone(t);return delete t.executionId,delete t.skillName,t.requiredMcpTools=[],t.lastActivityAt=Date.now(),this.persist(t),o}addEvidenceObligation(e,t,o=Date.now(),r){let i=this.registerSession(e),a=(r?void 0:i.evidenceObligations.find(u=>u.contractId===t.id))?.obligationId??Se(t.id,r,o);this.appendEvidenceEvent(e,{kind:"add",obligationId:a,contractId:t.id,at:o,contract:t},`add\0${a}`),this.replayEvidenceJournal(i);let c=i.evidenceObligations.find(u=>u.obligationId===a);return c?(i.lastActivityAt=Date.now(),this.persist(i),structuredClone(c)):null}listEvidenceObligations(e){return (this.get(e)?.evidenceObligations??[]).map(t=>structuredClone(t))}markEvidenceCorrection(e,t,o,r,i=Date.now()){let s=this.get(e),a=s?.evidenceObligations.find(d=>d.obligationId===t);if(!s||!a)return null;let c=/^[a-f0-9]{64}$/.test(r)?r:"";if(!c)return null;this.appendEvidenceEvent(e,{kind:"correction",obligationId:t,contractId:a.contractId,at:i,fingerprint:c,violations:o.slice(0,16).map(d=>d.slice(0,240))},`correction\0${t}\0${c}`),this.replayEvidenceJournal(s),s.lastActivityAt=i,this.persist(s);let u=s.evidenceObligations.find(d=>d.obligationId===t);return u?structuredClone(u):null}resolveEvidenceObligation(e,t){let o=this.get(e);if(!o)return false;let r=o.evidenceObligations.find(s=>s.obligationId===t);if(!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve\0${t}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}resolveDegradedEvidence(e,t){let o=this.get(e),r=o?.evidenceDegradations.find(s=>s.obligationId===t);if(!o||!r)return false;let i=Date.now();return this.appendEvidenceEvent(e,{kind:"resolve",obligationId:t,contractId:r.contractId,at:i},`resolve-degraded\0${t}\0${i}`),this.replayEvidenceJournal(o),o.lastActivityAt=i,this.persist(o),true}degradeEvidenceObligation(e,t,o,r=Date.now()){let i=this.get(e),s=i?.evidenceObligations.find(c=>c.obligationId===t);if(!i||!s)return false;let a=o.slice(0,240);return this.appendEvidenceEvent(e,{kind:"degrade",obligationId:t,contractId:s.contractId,at:r,reason:a},`degrade\0${t}\0${a}`),this.replayEvidenceJournal(i),i.lastActivityAt=r,this.persist(i),true}removeSession(e){let t=e.trim();t&&(this.sessions.delete(t),rmSync(this.snapshotPath(t),{force:true}),rmSync(this.evidenceJournalDir(t),{recursive:true,force:true}));}list(){return [...this.sessions.values()]}snapshotPath(e){return join$1(this.sessionsDir,`${z(e)}.json`)}evidenceJournalDir(e){return join$1(this.sessionsDir,"evidence-journal",z(e))}appendEvidenceEvent(e,t,o){let r=this.evidenceJournalDir(e);mkdirSync$1(r,{recursive:true,mode:448});let i=createHash$1("sha256").update(o).digest("hex"),s=join$1(r,`${t.kind}-${i}.json`);if(existsSync$1(s))return;let a=join$1(r,`.${process.pid}.${randomUUID()}.tmp`);writeFileSync$1(a,JSON.stringify(t),{mode:384});try{linkSync(a,s);}catch(c){if(c.code!=="EEXIST")throw c}finally{rmSync(a,{force:true});}}replayEvidenceJournal(e){e.evidenceObligations=B(e.evidenceObligations),e.evidenceDegradations=J(e.evidenceDegradations),e.evidenceOutcomes=W(e.evidenceOutcomes);let t=this.evidenceJournalDir(e.sessionId);if(!existsSync$1(t))return;let o;try{o=readdirSync(t).filter(i=>/^(?:add|correction|resolve|degrade)-[a-f0-9]{64}\.json$/.test(i)).slice(0,4096);}catch{return}let r=o.flatMap(i=>{try{let s=readFileSync$1(join$1(t,i),"utf8");if(Buffer.byteLength(s,"utf8")>64*1024)return [];let a=Re(JSON.parse(s));return a?[a]:[]}catch{return []}}).sort((i,s)=>i.at-s.at||G(i.kind)-G(s.kind));for(let i of r)this.applyEvidenceEvent(e,i);e.evidenceObligations=e.evidenceObligations.slice(-8),e.evidenceDegradations=e.evidenceDegradations.slice(-20),e.evidenceOutcomes=e.evidenceOutcomes.slice(-20);}applyEvidenceEvent(e,t){let o=e.evidenceOutcomes.find(s=>s.obligationId===t.obligationId);if(t.kind==="add"){if(o)return;let s=e.evidenceObligations.find(a=>a.obligationId===t.obligationId);s?(s.contract=t.contract,s.promptedAt=Math.min(s.promptedAt,t.at)):e.evidenceObligations.push({obligationId:t.obligationId,contractId:t.contractId,contract:t.contract,promptedAt:t.at,attempt:0,correctionRequested:false,violations:[]});return}let r=e.evidenceObligations.find(s=>s.obligationId===t.obligationId);if(t.kind==="correction"){if(!r||o||r.correctionFingerprint===t.fingerprint)return;r.attempt+=1,r.correctionRequested=true,r.correctionRequestedAt=t.at,r.correctionFingerprint=t.fingerprint,r.violations=t.violations;return}let i=r?.attempt??o?.attempt??0;if(t.kind==="resolve"&&o?.status==="degraded")e.evidenceOutcomes=e.evidenceOutcomes.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations=e.evidenceDegradations.filter(s=>s.obligationId!==t.obligationId);else if(o)return;t.kind==="degrade"?(e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceDegradations.push({obligationId:t.obligationId,contractId:t.contractId,reason:t.reason,degradedAt:t.at,attempt:i,contract:r?.contract})):e.evidenceObligations=e.evidenceObligations.filter(s=>s.obligationId!==t.obligationId),e.evidenceOutcomes.push({obligationId:t.obligationId,contractId:t.contractId,status:t.kind==="resolve"?"resolved":"degraded",completedAt:t.at,attempt:i,...t.kind==="degrade"?{reason:t.reason}:{}});}persist(e){mkdirSync$1(this.sessionsDir,{recursive:true,mode:448});let t=this.snapshotPath(e.sessionId),o=`${t}.${process.pid}.${randomUUID()}.tmp`;writeFileSync$1(o,JSON.stringify(e),{mode:384}),renameSync$1(o,t);}};function B(n){return Array.isArray(n)?n.flatMap(e=>{if(!e||typeof e!="object")return [];let t=e;if(typeof t.contractId!="string"||t.contractId.length===0||t.contractId.length>128||typeof t.promptedAt!="number"||typeof t.attempt!="number"||typeof t.correctionRequested!="boolean"||!Array.isArray(t.violations)||!Y(t.contract))return [];let o=typeof t.obligationId=="string"&&t.obligationId.length>0&&t.obligationId.length<=384?t.obligationId:V(t.contractId),r=typeof t.correctionTranscriptHash=="string"?t.correctionTranscriptHash:void 0,i=t.correctionFingerprint??r;return i!==void 0&&!/^[a-f0-9]{64}$/.test(i)?[]:[{...t,obligationId:o,correctionFingerprint:i}]}).slice(-8):[]}function J(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&typeof t.reason=="string"&&typeof t.degradedAt=="number"&&typeof t.attempt=="number"}).slice(-20):[]}function W(n){return Array.isArray(n)?n.filter(e=>{if(!e||typeof e!="object")return false;let t=e;return typeof t.obligationId=="string"&&typeof t.contractId=="string"&&(t.status==="resolved"||t.status==="degraded")&&typeof t.completedAt=="number"&&typeof t.attempt=="number"&&(t.reason===void 0||typeof t.reason=="string")}).slice(-20):[]}function Re(n){if(!n||typeof n!="object")return null;let e=n,t=e.kind;if(t!=="add"&&t!=="correction"&&t!=="resolve"&&t!=="degrade"||typeof e.contractId!="string"||e.contractId.length>128||typeof e.at!="number")return null;let r={obligationId:typeof e.obligationId=="string"&&e.obligationId.length>0&&e.obligationId.length<=384?e.obligationId:V(e.contractId),contractId:e.contractId,at:e.at};if(t==="add")return Y(e.contract)?{kind:t,...r,contract:e.contract}:null;if(t==="correction"){let i=typeof e.fingerprint=="string"?e.fingerprint:e.transcriptHash;return typeof i=="string"&&/^[a-f0-9]{64}$/.test(i)&&Array.isArray(e.violations)&&e.violations.every(s=>typeof s=="string"&&s.length<=240)?{kind:t,...r,fingerprint:i,violations:e.violations}:null}return t==="resolve"?{kind:t,...r}:typeof e.reason=="string"&&e.reason.length<=240?{kind:t,...r,reason:e.reason}:null}function G(n){return n==="add"?0:n==="correction"?1:2}function Y(n){if(!n||typeof n!="object")return false;let e=n,t=e.requiredSections,o=e.prohibitedClaims;return e.version==="1.0"&&typeof e.id=="string"&&/^[a-zA-Z0-9][a-zA-Z0-9:._-]{0,127}$/.test(e.id)&&typeof e.runtimeProfilingOccurred=="boolean"&&typeof e.samplingEvidenceOccurred=="boolean"&&Array.isArray(t)&&t.length===3&&t[0]==="\u5DE5\u5177\u53D1\u73B0"&&t[1]==="\u6A21\u578B\u5047\u8BBE"&&t[2]==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&Array.isArray(o)&&o.length<=16&&o.every(r=>typeof r=="string"&&r.length<=128)&&typeof e.canonicalReport=="string"&&Buffer.byteLength(e.canonicalReport,"utf8")<=48*1024&&!!e.correctionPolicy&&e.correctionPolicy.maxAttempts===1&&e.correctionPolicy.repeatedViolation==="fail_open"}function T(n,e,t){try{let o=openGlobalDevFlowDatabase();try{o.insertEvent({kind:n,timestamp:Date.now(),duration:t,success:e.success!==!1,metadata:e});}finally{o.close();}}catch{}}var Fe=getLocalApiKey(),D=join(getDevFlowStateRoot(),"errors");async function k(n,e,t={}){let o=t.endpoint??process.env.DEVFLOW_SERVER_URL?.trim()??Le();if(!o)return {delivered:false,suppressed:false,fallbackReason:"runtime_not_ready"};let r=t.timeout??1500,i=t.durableMirror??true,s=t.maxRetries??(i?0:2),a=t.circuitBreaker??true,c=acquireRuntimeHttpCircuit(o,n);if(a&&!c.allowed)return {delivered:false,suppressed:true,fallbackReason:c.state.fallbackReason};let u;for(let l=0;l<=s;l+=1)try{return await Ne(o,n,e,r),a&&registerRuntimeHttpSuccess(o,n).transitioned&&T("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"closed",failures:0}),{delivered:!0,suppressed:!1}}catch(m){u=m instanceof Error?m:new Error(String(m)),l<s&&await qe(Math.min(100*2**l,1e3));}if(!u)return {delivered:false,suppressed:false,fallbackReason:"unknown_http_failure"};if(!a)return X(n,u),{delivered:false,suppressed:false,fallbackReason:u.message};let d=registerRuntimeHttpFailure(o,n,t.fallbackReason??(i?"local_durable_mirror":"http_delivery_failed"));return d.transitioned&&(X(n,u),T("http_circuit_transition",{endpoint:o,path:new URL(n,o).pathname,previous:c.state.status,status:"open",failures:d.state.failures,openUntil:d.state.openUntil,fallbackReason:d.state.fallbackReason})),{delivered:false,suppressed:false,fallbackReason:d.state.fallbackReason}}function Le(){let n=readRuntimeState();return n?.status==="ready"&&n.dashboardAvailable?n.url:void 0}function Ne(n,e,t,o){return new Promise((r,i)=>{let s=JSON.stringify(t),a=new URL(e,n),c=false,u=l=>{c||(c=true,l?i(l):r());},d=request({hostname:a.hostname,port:a.port,path:a.pathname+a.search,method:"POST",headers:{"Content-Type":"application/json","X-API-Key":Fe,"Content-Length":Buffer.byteLength(s)},timeout:o},l=>{l.on("error",u),l.on("end",()=>{let m=l.statusCode??0;u(m>=200&&m<300?void 0:new Error(`HTTP ${m}`));}),l.resume();});d.on("error",u),d.on("timeout",()=>d.destroy(new Error(`HTTP mirror timed out after ${o}ms`))),d.write(s),d.end();})}function X(n,e){try{existsSync(D)||mkdirSync(D,{recursive:!0});let t=join(D,"http-errors.log"),o=`${new Date().toISOString()} | ${n} | ${e.message}
2
+ `;rotateDiagnosticLogFile({path:t,maxBytes:50*1024*1024,maxFiles:5,incomingBytes:Buffer.byteLength(o)}),appendFileSync(t,o);}catch{}}function qe(n){return new Promise(e=>setTimeout(e,n))}function te(n,e){let t=Je(n);mkdirSync(t,{recursive:true,mode:448});let o=join(t,`${e.receiptId}.json`);if(existsSync(o))return e.receiptId;let r=`${o}.${process.pid}.tmp`;writeFileSync(r,JSON.stringify(e),{mode:384});try{renameSync(r,o);}catch(i){try{unlinkSync(r);}catch{}if(!existsSync(o))throw i}return e.receiptId}function Je(n){return join(w(n),"session-finalize-pending")}var p=emitSemanticControlLog;function O(n){let{projectRoot:e,...t}=n;try{return new M(e).dispatchBoundary(t).snapshot??null}catch(o){return p({event:"hook.runtime.degraded",identity:{projectRoot:e,sessionId:n.sessionId,...n.turnId?{turnId:n.turnId}:{},...n.requestId?{requestId:n.requestId}:{},...n.executionId?{executionId:n.executionId}:{}},level:"error",timestamp:Date.now(),data:{stage:n.kind,reason:o instanceof Error?o.message:String(o),tool:n.producer}}),null}}var M=class{constructor(e){this.projectRoot=e;}dispatchBoundary(e){let t=Xe(e.kind,e.payload??{});if(!t)return {handled:false};let o=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let r=Ye(o,{projectRoot:this.projectRoot,sessionId:e.sessionId,...e.turnId?{turnId:e.turnId}:{},...e.requestId?{requestId:e.requestId}:{},...e.executionId?{executionId:e.executionId}:{}});return r?{handled:!0,snapshot:new TaskKernel(new TaskEventStore(o),new SemanticRuntimeEventProjector).dispatch({definition:r.definition,kind:t.kind,payload:t.payload,idempotencyKey:`host:${r.definition.definitionHash}:${e.dedupeKey}`,producer:e.producer}).snapshot}:{handled:!1}}finally{o.close();}}};function Ye(n,e){let t=e.executionId?n.getActiveContextReceipt(e.projectRoot,e.sessionId,e.executionId):null,o=e.turnId??t?.canonicalAction?.binding.turnId,r=e.requestId??t?.requestId;if(!o&&!r)return null;let i=n.listLatestTaskIntentArtifacts(e.projectRoot,e.sessionId).find(c=>o?c.turnId===o:c.requestId===r);if(!i)return null;let s=n.getTaskAggregateSnapshot(e.projectRoot,e.sessionId,i.turnId,i.version);if(!s)return null;let a=n.getTaskDefinitionV2(s.taskDefinitionHash);return !a||a.revision!==i.version?null:{definition:a,snapshot:s}}function Xe(n,e){switch(n){case "action.lease.issued":return {kind:"action_lease_issued",payload:e};case "action.succeeded":return {kind:"action_completed",payload:e};case "action.failed":return {kind:"action_failed",payload:e};case "verification.succeeded":return {kind:"verification_completed",payload:e};case "verification.failed":return {kind:"verification_failed",payload:e};case "memory.committed":return {kind:"memory_episode_persisted",payload:e};case "memory.skipped":return {kind:"memory_decision_completed",payload:e};case "memory.pending":return {kind:"memory_extraction_queued",payload:e};case "memory.failed":return {kind:"memory_extraction_failed",payload:e};case "durable_work.owned":return {kind:"durable_work_leased",payload:{...e,fencingToken:Number.isSafeInteger(e.fencingToken)?e.fencingToken:0}};case "durable_work.completed":return {kind:"durable_work_completed",payload:e};case "durable_work.dead_lettered":return {kind:"durable_work_dead_lettered",payload:e};default:return null}}var ot=512*1024,rt=500;var it=["\u5DE5\u5177\u53D1\u73B0","\u6A21\u578B\u5047\u8BBE","\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"];function ie(n){let e=n.runtimeStore??new I(n.projectRoot),t=e.listEvidenceObligations(n.sessionId);if(t.length===0)return st(n,e),null;let o=$(n.transcriptPath,t);if(!o.answer){let s=o.degradationReason??"transcript_answer_unavailable";for(let a of t)e.degradeEvidenceObligation(n.sessionId,a.obligationId,s);return null}let r=o.fingerprint;if(!r){for(let s of t)e.degradeEvidenceObligation(n.sessionId,s.obligationId,"transcript_identity_unavailable");return null}let i=[];for(let s of t){let a=se(o.answer,[s]);if(a.length===0){e.resolveEvidenceObligation(n.sessionId,s.obligationId),x(n,s,"satisfied",r);continue}if(!s.correctionFingerprint){e.markEvidenceCorrection(n.sessionId,s.obligationId,a,r),i.push({obligation:s,violations:a}),x(n,s,"correction_requested",r,a);continue}if(s.correctionFingerprint===r){i.push({obligation:s,violations:a});continue}e.degradeEvidenceObligation(n.sessionId,s.obligationId,"evidence_contract_unresolved"),x(n,s,"degraded",r,a);}return i.length===0?null:at(i)}function st(n,e){let t=(e.get(n.sessionId)?.evidenceDegradations??[]).filter(i=>i.contract).slice(-8);if(t.length===0)return;let o=t.map(i=>({obligationId:i.obligationId,contractId:i.contractId,contract:i.contract,promptedAt:i.degradedAt,attempt:i.attempt,correctionRequested:true,violations:[]})),r=$(n.transcriptPath,o);if(!(!r.answer||!r.fingerprint))for(let i of o)se(r.answer,[i]).length>0||e.resolveDegradedEvidence(n.sessionId,i.obligationId)&&x(n,i,"satisfied",r.fingerprint);}function x(n,e,t,o,r=[]){t!=="correction_requested"&&O({projectRoot:n.projectRoot,sessionId:n.sessionId,kind:t==="satisfied"?"verification.succeeded":"verification.failed",payload:{receiptId:e.obligationId,reasonCode:t==="satisfied"?"performance_evidence_satisfied":"performance_evidence_unresolved"},dedupeKey:`${e.obligationId}:${t}:${e.attempt}`,producer:"devflow-evidence-contract"}),p({event:"verification.completed",identity:{projectRoot:n.projectRoot,sessionId:n.sessionId},level:t==="satisfied"?"info":t==="degraded"?"error":"warn",timestamp:Date.now(),data:{stage:"performance_evidence_transition",status:t,contractId:e.contractId,obligationId:e.obligationId,attempt:e.attempt,answerFingerprint:o,violations:r,supersedesDegradation:t==="satisfied"&&e.attempt>0}});}function at(n){let e=[...new Set(n.flatMap(o=>o.violations))],t=[...new Map(n.map(o=>[o.obligation.contractId,o.obligation.contract.canonicalReport])).values()];return {decision:"block",reason:["DevFlow evidence contract violation. Correct the final performance answer once before stopping.",`Violations: ${e.join("; ")}`,"Use this canonical report (you may add clearly labeled hypotheses or runtime verification steps, but no unsupported measured claims):",t.join(`
3
3
 
4
4
  ---
5
5
 
6
6
  `)].join(`
7
7
 
8
- `)}}function se(n,e){let t=new Set,o=new Set(e.flatMap(c=>c.contract.requiredSections)),r=ae(n.split(/\r?\n/)),i=ce(r.headingLines);for(let c of o)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<r.claimLines.length;c++){let u=r.claimLines[c].trim();if(!u||ct(u))continue;let d=i.byLine.get(c);for(let l of pt(u))lt(l,d,a,t);}return [...t]}function ae(n){let e=false,t=[],o=[];for(let r of n){if(/^\s*```/.test(r)){e=!e,t.push(""),o.push(r.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":r.replace(/`[^`]*`/g,"").trim()),o.push(r.replace(/`([^`]*)`/g,(i,s)=>at(s)?"":s).trim());}return {headingLines:t,claimLines:o}}function at(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function ct(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?dt(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function dt(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function lt(n,e,t,o){let r=/\bP0\b/gi;for(let y of n.matchAll(r))re(n,y.index??0,y[0],"p0")||o.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let y of n.matchAll(i))re(n,y.index??0,y[0],"high")||o.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let y of n.matchAll(s))mt(n,y.index??0,y[0])||(/(?:瓶颈|bottleneck)/i.test(y[0])?o.add("unsupported_confirmed_bottleneck"):o.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),u=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||u)&&c&&o.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let d=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),l=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!l&&o.add("unsupported_benefit_percentage"),d&&!l&&o.add("unsupported_performance_number");let m=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),h=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),g=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);m&&h&&!g&&!t&&o.add("raf_without_sampling_evidence");}function re(n,e,t,o){let r=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=ut(r),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:o==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(r)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(r):false}function ut(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,o=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||o.test(n)}function mt(n,e,t){let o=n.slice(Math.max(0,e-40),e),r=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(o)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(o),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(r)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(r);return i||s}function pt(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function $(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let o=lstatSync(n);if(!o.isFile()||o.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let r=fstatSync(t);if(!r.isFile()||r.dev!==o.dev||r.ino!==o.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(r.size,nt),s=Buffer.alloc(i),a=0;for(;a<i;){let g=readSync(t,s,a,i-a,r.size-i+a);if(g===0)break;a+=g;}let c=s.subarray(0,a).toString("utf8");r.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
9
- `)+1)));let u=c.split(/\r?\n/).slice(-ot),d=e.length>0?Math.min(...e.map(g=>g.promptedAt)):0,l=gt(u,d),h=[...l].reverse().find(g=>ft(g.text,e))??l.at(-1);return h?.text?{answer:h.text,fingerprint:h.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync(t);}}function ft(n,e){let t=new Set(e.flatMap(r=>r.contract.requiredSections)),o=ce(ae(n.split(/\r?\n/u)).headingLines);return [...t].every(r=>o.found.has(r))}function P(n){return $(n,[]).answer}function gt(n,e){let t=[];for(let o=0;o<n.length;o++){let r=n[o];if(r.trim())try{let i=JSON.parse(r),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=yt(i.timestamp);if(c>0&&c+5e3<e)continue;let u=s.content,d=typeof u=="string"?u:Array.isArray(u)?u.filter(l=>l&&typeof l=="object"&&l.type==="text").map(l=>l.text).filter(l=>typeof l=="string").join(`
10
- `):"";if(d.trim()){let l=d.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,h=createHash("sha256").update(l).digest("hex"),g=createHash("sha256").update(`${m}\0${h}`).digest("hex");t.push({text:l,timestamp:c,fingerprint:g});}}catch{continue}}return t}function yt(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function ce(n){let e=new Set,t=new Map,o;for(let r=0;r<n.length;r++){let i=n[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=rt.find(a=>i===a);s&&(o=s,e.add(s)),t.set(r,o);}return {found:e,byLine:t}}var vt={open:["intent_bound"],intent_bound:["context_ready","context_degraded"],context_ready:["action_required","action_not_required"],context_degraded:["action_required","action_not_required"],action_required:["action_satisfied","action_degraded","action_failed"],action_not_required:["memory_decided","memory_quarantined"],action_satisfied:["memory_decided","memory_quarantined"],action_degraded:["memory_decided","memory_quarantined"],action_failed:["action_satisfied","action_degraded"],memory_decided:["closed","closed_with_degradation","closed_with_retry_work"],memory_quarantined:["closed_with_degradation","closed_with_retry_work"],closed:[],closed_with_degradation:[],closed_with_retry_work:[]};function F(n){return bt(n)}function bt(n){let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let t=Rt(e,n.artifact);if(kt(t.toState))return t;let o=e.getContextReceiptForRequest(n.artifact.projectRoot,n.artifact.sessionId,n.artifact.requestId),r=e.getMemoryTurn(n.artifact.turnId),i=n.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return t;let s=o?_t(n.artifact,o):"context_ready";t.toState==="intent_bound"&&(t=f(e,t,n,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?wt(n.artifact,o):"action_not_required";if((t.toState==="context_ready"||t.toState==="context_degraded")&&(a==="action_not_required"?t=f(e,t,n,"action_not_required","task_action_not_required"):t=f(e,t,n,"action_required","canonical_action_obligation_present")),t.toState==="action_required"){if(a==="action_required")return t;if(a==="action_failed")return f(e,t,n,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?t=f(e,t,n,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(t=f(e,t,n,"action_satisfied","canonical_action_succeeded"));}if(t.toState==="action_failed")if(a==="action_satisfied")t=f(e,t,n,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")t=f(e,t,n,"action_degraded","canonical_action_retry_degraded");else return t;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(t.toState)&&(t=f(e,t,n,n.memoryStatus==="pending"?"memory_quarantined":"memory_decided",n.memoryStatus==="pending"?n.reason:`canonical_memory_${n.memoryStatus}`)),t.toState==="memory_decided"?f(e,t,n,c?"closed_with_degradation":"closed",n.reason):t.toState==="memory_quarantined"?f(e,t,n,n.retryOwned?"closed_with_retry_work":"closed_with_degradation",n.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):t}finally{e.close();}}function _t(n,e){return n.intent==="memory"||n.intent==="knowledge"||(e.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function wt(n,e){let t=e.canonicalAction,r=(t?(e.actionAttempts??[]).filter(i=>i.tool===t.tool):[]).at(-1);return e.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":e.actionDegradation||t?.status==="degraded"||t?.status==="unsupported"?"action_degraded":t?.required||St(n)?"action_required":"action_not_required"}function St(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function Rt(n,e){let t=n.getLatestTerminalTransition(e.projectRoot,e.sessionId,e.turnId);if(!t)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${e.turnId}`);return t}function f(n,e,t,o,r){if(!vt[e.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${e.toState}->${o}`);let i=e.sequence+1,s=`terminal:${createHash("sha256").update(`${t.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=n.appendTerminalTransition({projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,executionId:t.artifact.executionId,sequence:i,fromState:e.toState,toState:o,receiptId:s,sourceReceiptId:t.memoryReceiptId??e.receiptId,reason:r,payload:{memoryStatus:t.memoryStatus,retryOwned:t.retryOwned??false,sourceIntentHash:t.artifact.artifactHash},createdAt:Date.now()});return p({event:"terminal.state.transitioned",identity:{projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,...t.artifact.executionId?{executionId:t.artifact.executionId}:{}},level:o==="closed"?"info":o.includes("degradation")||o.includes("retry")||o==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:e.toState,nextState:o,receiptId:s,reason:r}}),a}function kt(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function de(n){let e={committed:0,skipped:0,pending:0},t=[];for(let o of n)e[o.status]+=1,o.receiptId&&t.push(o.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function Et(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}function Ct(n,e=_(),t=true,o,r=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:o},u;try{u=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let d=u.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),l=u.getWorkByIdempotencyKey(a),m={status:d.state==="closed"||d.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:l?.state??"pending",closureState:d.state,pendingWorkCount:d.pendingWorkCount,...l?.id?{workItemId:l.id}:{}};return p({event:"hook.session_end.completed",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(d){if(!r)throw d;return te(e,{receiptId:a,...c}),p({event:"hook.session_end.degraded",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:Et(d),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{u?.close();}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=Ct(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var A=1,Pt="memory-snapshot-v1.json",Ft=512*1024,pe=256*1024,fe=2e3,qt=500,Nt=10,Lt=240,Ht=300*1e3,zt=720*60*60*1e3,Ut=2147483647;function Bt(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function b(n){return resolve(n)}function S(n){return createHash("sha256").update(b(n)).digest("hex").slice(0,16)}function Jt(n,e={}){let t=S(n),o=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(b(n));return join(o,Pt)}function Wt(n,e){let o=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${e}:${o}`:e}function N(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Gt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&N(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Kt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function ge(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let o=n,r=b(e),i=S(r),s=o.generation===void 0?0:o.generation;return o.version!==A||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>pe||!N(o.memoryIds,fe)||!Array.isArray(o.conflicts)||o.conflicts.length>qt||!o.conflicts.every(Gt)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>t+Ht||!Number.isInteger(s)||s<0||s>Ut||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!Kt(o.degradation)?null:{...o,generation:s}}function Vt(n,e,t,o,r=0){let i=b(n);return {version:A,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:e,degradation:{reason:t}}}function Xt(n,e={}){let t=e.now??Date.now(),o=Jt(n,e),r;try{r=openSync(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(r);if(!i.isFile()||i.size<=0||i.size>Ft)throw new Error("cache_size_invalid");let s=Bt({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(r,"utf8")),c=ge(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>zt?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:Vt(n,a?"pending":"degraded",a?"cache_missing":Wt(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync(r);}catch{}}}function Yt(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function Zt(n,e,t){if(!e.trim())return null;try{let o=JSON.parse(e);if(o.status!=="ok"&&o.status!=="degraded")return null;if(o.enabled===!1){let i=b(n);return {version:A,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let r=ge(o.snapshot,n,t);if(r)return r;if(o.status==="ok"&&typeof o.markdown=="string"&&o.markdown.length>0&&Buffer.byteLength(o.markdown,"utf8")<=pe){let i=b(n);return {version:A,projectRoot:i,projectHash:S(i),markdown:o.markdown,memoryIds:N(o.memoryIds,fe)?o.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function q(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,Lt).join("")}function Qt(n){if(n.length===0)return "";let e=n.slice(0,Nt),t=e.map(o=>{let r=q(o.family,"unknown"),i=q(o.entity,"unknown"),s=q(o.summary,"Explicit choice required.");return `- family=${r}; entity=${i}; status=${o.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
8
+ `)}}function se(n,e){let t=new Set,o=new Set(e.flatMap(c=>c.contract.requiredSections)),r=ae(n.split(/\r?\n/)),i=ce(r.headingLines);for(let c of o)i.found.has(c)||t.add(`missing_section:${c}`);if(e.every(c=>c.contract.runtimeProfilingOccurred))return [...t];let a=e.every(c=>c.contract.samplingEvidenceOccurred);for(let c=0;c<r.claimLines.length;c++){let u=r.claimLines[c].trim();if(!u||dt(u))continue;let d=i.byLine.get(c);for(let l of ft(u))ut(l,d,a,t);}return [...t]}function ae(n){let e=false,t=[],o=[];for(let r of n){if(/^\s*```/.test(r)){e=!e,t.push(""),o.push(r.replace(/^\s*```+[^\s`]*/,"").replace(/```+\s*$/,"").trim());continue}t.push(e?"":r.replace(/`[^`]*`/g,"").trim()),o.push(r.replace(/`([^`]*)`/g,(i,s)=>ct(s)?"":s).trim());}return {headingLines:t,claimLines:o}}function ct(n){let e=n.trim().slice(0,256);return !e||/\s/.test(e)||n.trim().length>256?false:/^[A-Za-z_$][\w$.-]*$/.test(e)||/^(['"])[^'"`]*\1$/.test(e)}function dt(n){if(n.length>2048)return false;let e=n.replace(/^\s*(?:[-*+]|\d+[.)])\s+/,"").trim();return e?lt(e)||/^(?:\/\/|\/\*|\*\/|\*\s|#!)/.test(e)||/^(?:import|export|const|let|var|function|class|type|interface|enum|namespace|declare)\b/.test(e)||/^(?:async\s+)?(?:function\s+)?[A-Za-z_$][\w$]*\s*=\s*/.test(e)||/^[A-Za-z_$][\w$.[\]'"-]*\s*(?:=|\+=|-=|\*=|\/=|\?\?=|&&=|\|\|=)\s*/.test(e)||/^[A-Za-z_$'"-][\w$.'"-]*\s*:\s*[^:]+[,}]?$/.test(e)||/=>/.test(e)||/^(?:await\s+|return\s+|throw\s+|new\s+)?[A-Za-z_$][\w$.]*\s*\([^)]*\)\s*;?$/.test(e)||/^(['"])[\s\S]*\1[;,]?$/.test(e)?true:/[{}()[\]=<>]\s*;?$/.test(e)&&/(?:;|=>|\b(?:return|new|await)\b)/.test(e):false}function lt(n){if(n.length>1024)return false;let e="(?:--[A-Za-z0-9_-]+|(?:-webkit-|-moz-|-ms-)?(?:animation(?:-[a-z-]+)?|transition(?:-[a-z-]+)?|opacity|transform|will-change|contain|content-visibility|display|position|top|right|bottom|left|width|height|min-(?:width|height)|max-(?:width|height)|margin(?:-[a-z]+)?|padding(?:-[a-z]+)?|color|background(?:-[a-z-]+)?|border(?:-[a-z-]+)?|font(?:-[a-z-]+)?|line-height|z-index|overflow(?:-[xy])?))";return new RegExp(`^${e}\\s*:\\s*\\S[^;]{0,960};$`,"i").test(n)}function ut(n,e,t,o){let r=/\bP0\b/gi;for(let y of n.matchAll(r))re(n,y.index??0,y[0],"p0")||o.add("unsupported_p0_severity");let i=/(?:中高|高)(?:风险|优先级)|严重(?:问题|风险)|\bhigh[- ](?:risk|severity|priority)\b/gi;for(let y of n.matchAll(i))re(n,y.index??0,y[0],"high")||o.add("unsupported_high_severity");let s=/(?:性能)?瓶颈|卡顿|掉帧|CPU\s*(?:热点|尖峰)|\bbottleneck\b|\bjank\b|\bdropped frames?\b|\bCPU hotspot\b/gi;for(let y of n.matchAll(s))pt(n,y.index??0,y[0])||(/(?:瓶颈|bottleneck)/i.test(y[0])?o.add("unsupported_confirmed_bottleneck"):o.add("unsupported_runtime_effect"));let a=/\b\d{1,3}(?:\.\d+)?\s*%/.test(n),c=/(?:预计|预期|估计|提升|降低|减少|节省|改善|收益|加速|improve|reduce|faster|gain|benefit|speedup|expected|estimated)/i.test(n),u=/\b\d+(?:\.\d+)?\s*[x×]\b/i.test(n);(a||u)&&c&&o.add(a?"unsupported_benefit_percentage":"unsupported_performance_number");let d=/\b\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:ms|fps|hz)\b/i.test(n)||/\d+(?:\.\d+)?(?:\s*[-–~]\s*\d+(?:\.\d+)?)?\s*(?:毫秒|次\s*\/\s*秒|帧)/.test(n),l=e==="\u9700\u8981\u8FD0\u884C\u65F6\u9A8C\u8BC1"&&/(?:采集|记录|测量|收集|collect|measure|record)/i.test(n)&&!/(?:预计|预期|估计|约|大约|通常|平均|每(?:隔)?|达到|提升|降低|减少|节省|改善|improve|reduce|faster|expected|estimated|average|typically|every)/i.test(n);a&&!c&&!l&&o.add("unsupported_benefit_percentage"),d&&!l&&o.add("unsupported_performance_number");let m=/(?:requestAnimationFrame|\bRAF\b)/i.test(n),h=/(?:建议|应该|应当|使用|添加|采用|切换|包裹|优化|节流|\buse\b|\badopt\b|\brecommend\b|\bswitch\b|\bwrap\b|\bthrottl(?:e|ing)\b)/i.test(n),g=/(?:不要|不得|不能|不应|避免|不建议|不推荐).{0,16}(?:使用|采用|添加|切换|包裹|节流)?.{0,8}(?:requestAnimationFrame|\bRAF\b)|\b(?:do\s+not|don't|never|avoid)\s+(?:use|adopt|recommend|switch|wrap|throttle)?.{0,8}(?:requestAnimationFrame|RAF)\b/i.test(n);m&&h&&!g&&!t&&o.add("raf_without_sampling_evidence");}function re(n,e,t,o){let r=n.slice(Math.max(0,e-64),e),i=n.slice(e+t.length,e+t.length+28),s=mt(r),a=/^(?:\s+)?(?:未发现|不存在|并不存在|未被发现)/.test(i)||/^(?:\s+)?(?:was\s+|is\s+)?not found\b/i.test(i);return s||a?true:o==="high"?/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?)\s*(?:任何|明确的)?\s*P0\s*(?:或|和|及|、)\s*$/i.test(r)||/\b(?:no evidence (?:of|for)|no)\s+P0\s+(?:or|and)\s+$/i.test(r):false}function mt(n){if(/(?:未发现|没有发现|不存在|无证据(?:表明|证明)?|不是|并非|未被)\s*(?:任何|明确的)?\s*(?:(?:问题|发现|证据|项|内容)\s*)?(?:(?:属于|(?:被)?(?:评|判定|认定|标记|列|视|定|归(?:类)?)为)\s*)?$/i.test(n)||/\b(?:no evidence (?:of|for)|no|not|isn't|is\s+not)\s+(?:an?\s+)?(?:(?:issues?|findings?|evidence|items?)\s+)?(?:(?:classified|rated|marked|labelled|labeled)(?:\s+as)?\s+)?$/i.test(n))return true;let t=/(?:不得|不能|不应|不宜|不要)\s*(?:被\s*)?(?:(?:直接|轻易|简单|明确|正式|合理|据此|当前|目前)\s*){0,2}(?:(?:评|判定|认定|标记|列|视|定|归(?:类)?)为|属于)\s*$/i,o=/\b(?:cannot|can't|must not|should not|shouldn't|do not|don't)\s+(?:(?:reasonably|directly|formally|currently)\s+){0,2}(?:be\s+)?(?:classified|labeled|labelled|rated|marked)(?:\s+as)?\s+$/i;return t.test(n)||o.test(n)}function pt(n,e,t){let o=n.slice(Math.max(0,e-40),e),r=n.slice(e+t.length,e+t.length+32),i=/(?:是否|待验证|候选|可能|潜在|未观察到|没有观察到|未发现|不存在|无证据(?:表明)?|不能(?:据此)?确认|尚未(?:确认|证明)|验证(?:是否)?|测量(?:是否)?|采集|记录|收集).{0,16}$/i.test(o)||/\b(?:whether|measure|validate|candidate|potential|possible|may|might|no|no evidence(?: of| for)?|not observed|unobserved|collect|record).{0,18}$/i.test(o),s=/^(?:是否|有待验证|待验证|候选|可能|潜在|指标|需要(?:验证|测量)|需(?:验证|测量))/.test(r)||/^(?:\s+)?(?:candidate|potential|possible|metric|metrics|to (?:measure|validate)|needs? (?:measurement|validation)|is (?:a )?(?:candidate|potential))/i.test(r);return i||s}function ft(n){return n.split(/(?:[。!?;;,,]|\b(?:but|however|yet|nevertheless|nonetheless)\b|但是|但|然而|却|不过|可是)/i).map(e=>e.trim()).filter(Boolean)}function $(n,e){if(!n||n.length>4096)return {degradationReason:"transcript_path_missing"};let t;try{let o=lstatSync(n);if(!o.isFile()||o.isSymbolicLink())return {degradationReason:"transcript_path_unsafe"};t=openSync(n,constants.O_RDONLY|(constants.O_NOFOLLOW??0));let r=fstatSync(t);if(!r.isFile()||r.dev!==o.dev||r.ino!==o.ino)return {degradationReason:"transcript_path_changed"};let i=Math.min(r.size,ot),s=Buffer.alloc(i),a=0;for(;a<i;){let g=readSync(t,s,a,i-a,r.size-i+a);if(g===0)break;a+=g;}let c=s.subarray(0,a).toString("utf8");r.size>i&&(c=c.slice(Math.max(0,c.indexOf(`
9
+ `)+1)));let u=c.split(/\r?\n/).slice(-rt),d=e.length>0?Math.min(...e.map(g=>g.promptedAt)):0,l=yt(u,d),h=[...l].reverse().find(g=>gt(g.text,e))??l.at(-1);return h?.text?{answer:h.text,fingerprint:h.fingerprint}:{degradationReason:"transcript_answer_unavailable"}}catch{return {degradationReason:"transcript_unreadable"}}finally{t!==void 0&&closeSync(t);}}function gt(n,e){let t=new Set(e.flatMap(r=>r.contract.requiredSections)),o=ce(ae(n.split(/\r?\n/u)).headingLines);return [...t].every(r=>o.found.has(r))}function P(n){return $(n,[]).answer}function yt(n,e){let t=[];for(let o=0;o<n.length;o++){let r=n[o];if(r.trim())try{let i=JSON.parse(r),s=i.message;if(!s||typeof s!="object"||s.role!=="assistant")continue;let a=s,c=ht(i.timestamp);if(c>0&&c+5e3<e)continue;let u=s.content,d=typeof u=="string"?u:Array.isArray(u)?u.filter(l=>l&&typeof l=="object"&&l.type==="text").map(l=>l.text).filter(l=>typeof l=="string").join(`
10
+ `):"";if(d.trim()){let l=d.trim(),m=typeof a.id=="string"&&a.id?`message:${a.id}`:typeof i.uuid=="string"&&i.uuid?`uuid:${i.uuid}`:`record:${String(i.timestamp??"")}:${o}:${createHash("sha256").update(r).digest("hex")}`,h=createHash("sha256").update(l).digest("hex"),g=createHash("sha256").update(`${m}\0${h}`).digest("hex");t.push({text:l,timestamp:c,fingerprint:g});}}catch{continue}}return t}function ht(n){if(typeof n=="number"&&Number.isFinite(n))return n;if(typeof n!="string")return 0;let e=Date.parse(n);return Number.isFinite(e)?e:0}function ce(n){let e=new Set,t=new Map,o;for(let r=0;r<n.length;r++){let i=n[r].trim().replace(/^#{1,6}\s*/,"").replace(/^\*\*(.*)\*\*$/,"$1").replace(/^(?:[一二三123][、..]\s*)/,"").replace(/[::]\s*$/,"").trim(),s=it.find(a=>i===a);s&&(o=s,e.add(s)),t.set(r,o);}return {found:e,byLine:t}}var bt={open:["intent_bound"],intent_bound:["context_ready","context_degraded"],context_ready:["action_required","action_not_required"],context_degraded:["action_required","action_not_required"],action_required:["action_satisfied","action_degraded","action_failed"],action_not_required:["memory_decided","memory_quarantined"],action_satisfied:["memory_decided","memory_quarantined"],action_degraded:["memory_decided","memory_quarantined"],action_failed:["action_satisfied","action_degraded"],memory_decided:["closed","closed_with_degradation","closed_with_retry_work"],memory_quarantined:["closed_with_degradation","closed_with_retry_work"],closed:[],closed_with_degradation:[],closed_with_retry_work:[]};function F(n){return _t(n)}function _t(n){let e=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:250});try{let t=kt(e,n.artifact);if(xt(t.toState))return t;let o=e.getContextReceiptForRequest(n.artifact.projectRoot,n.artifact.sessionId,n.artifact.requestId),r=e.getMemoryTurn(n.artifact.turnId),i=n.artifact.intent==="memory"||r?.source==="explicit_intent";if(!o&&!i)return t;let s=o?wt(n.artifact,o):"context_ready";t.toState==="intent_bound"&&(t=f(e,t,n,s,i?"task_context_not_required":s==="context_ready"?"canonical_context_receipt_ready":"canonical_context_receipt_degraded"));let a=o?St(n.artifact,o):"action_not_required";if((t.toState==="context_ready"||t.toState==="context_degraded")&&(a==="action_not_required"?t=f(e,t,n,"action_not_required","task_action_not_required"):t=f(e,t,n,"action_required","canonical_action_obligation_present")),t.toState==="action_required"){if(a==="action_required")return t;if(a==="action_failed")return f(e,t,n,"action_failed","canonical_action_attempt_failed");a==="action_degraded"?t=f(e,t,n,"action_degraded","canonical_action_unavailable_or_degraded"):a==="action_satisfied"&&(t=f(e,t,n,"action_satisfied","canonical_action_succeeded"));}if(t.toState==="action_failed")if(a==="action_satisfied")t=f(e,t,n,"action_satisfied","canonical_action_retry_succeeded");else if(a==="action_degraded")t=f(e,t,n,"action_degraded","canonical_action_retry_degraded");else return t;let c=s==="context_degraded"||a==="action_degraded";return ["action_not_required","action_satisfied","action_degraded"].includes(t.toState)&&(t=f(e,t,n,n.memoryStatus==="pending"?"memory_quarantined":"memory_decided",n.memoryStatus==="pending"?n.reason:`canonical_memory_${n.memoryStatus}`)),t.toState==="memory_decided"?f(e,t,n,c?"closed_with_degradation":"closed",n.reason):t.toState==="memory_quarantined"?f(e,t,n,n.retryOwned?"closed_with_retry_work":"closed_with_degradation",n.retryOwned?"durable_retry_owner_confirmed":"terminal_obligation_unowned"):t}finally{e.close();}}function wt(n,e){return n.intent==="memory"||n.intent==="knowledge"||(e.selectedFiles?.length??0)>0?"context_ready":"context_degraded"}function St(n,e){let t=e.canonicalAction,r=(t?(e.actionAttempts??[]).filter(i=>i.tool===t.tool):[]).at(-1);return e.actionSatisfiedAt||r?.status==="succeeded"?"action_satisfied":r&&["failed","timeout","unavailable"].includes(r.status)?"action_failed":e.actionDegradation||t?.status==="degraded"||t?.status==="unsupported"?"action_degraded":t?.required||Rt(n)?"action_required":"action_not_required"}function Rt(n){return ["create","modify","debug","test","format"].includes(n.action)||["feature","refactor","performance"].includes(n.intent)}function kt(n,e){let t=n.getLatestTerminalTransition(e.projectRoot,e.sessionId,e.turnId);if(!t)throw new Error(`TERMINAL_INTENT_STATE_MISSING:${e.turnId}`);return t}function f(n,e,t,o,r){if(!bt[e.toState]?.includes(o))throw new Error(`TERMINAL_PATH_UNAVAILABLE:${e.toState}->${o}`);let i=e.sequence+1,s=`terminal:${createHash("sha256").update(`${t.artifact.artifactHash}\0${i}\0${o}`).digest("hex").slice(0,24)}`,a=n.appendTerminalTransition({projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,executionId:t.artifact.executionId,sequence:i,fromState:e.toState,toState:o,receiptId:s,sourceReceiptId:t.memoryReceiptId??e.receiptId,reason:r,payload:{memoryStatus:t.memoryStatus,retryOwned:t.retryOwned??false,sourceIntentHash:t.artifact.artifactHash},createdAt:Date.now()});return p({event:"terminal.state.transitioned",identity:{projectRoot:t.artifact.projectRoot,projectId:t.artifact.projectId,hostId:t.artifact.hostId,sessionId:t.artifact.sessionId,turnId:t.artifact.turnId,requestId:t.artifact.requestId,...t.artifact.executionId?{executionId:t.artifact.executionId}:{}},level:o==="closed"?"info":o.includes("degradation")||o.includes("retry")||o==="action_failed"?"warn":"info",timestamp:Date.now(),data:{fromState:e.toState,nextState:o,receiptId:s,reason:r}}),a}function xt(n){return n==="closed"||n==="closed_with_degradation"||n==="closed_with_retry_work"}function de(n,e){let t=join(n,".devflow","delivery-line","state.db");if(!existsSync(t)||!e.trim())return 0;let o;try{o=new DatabaseSync(t,{timeout:250});let r=o.prepare("SELECT id FROM delivery_cases WHERE id = ? OR json_extract(payload, '$.sessionId') = ?").all(e,e),i=0,s=!!o.prepare("SELECT 1 FROM sqlite_master WHERE type = 'table' AND name = 'delivery_events'").get();for(let a of r)if(i+=Number(o.prepare("UPDATE delivery_tasks SET lease_owner = NULL, lease_expires_at = NULL WHERE case_id = ? AND lease_owner IS NOT NULL").run(a.id).changes),s){let c=`session.closed:${a.id}:${e}`;o.prepare("INSERT OR IGNORE INTO delivery_events (id,case_id,idempotency_key,actor,type,payload,created_at,processed_at) VALUES (?,?,?,?,?,?,?,NULL)").run(c,a.id,c,JSON.stringify({id:"devflow:session-end",kind:"system"}),"session.closed",JSON.stringify({sessionId:e,releasedLeases:i}),Date.now());}return i}catch{return 0}finally{o?.close();}}function le(n){let e={committed:0,skipped:0,pending:0},t=[];for(let o of n)e[o.status]+=1,o.receiptId&&t.push(o.receiptId);return {memoryReceiptIds:[...new Set(t)],missingMemoryDecisionCount:e.pending,memoryTurnOutcomes:e}}function Mt(n){return (n instanceof Error?n.message:String(n)).trim().slice(0,240)||"memory_lifecycle_unavailable"}function Ot(n,e=_(),t=true,o,r=true){let i;try{i=JSON.parse(n);}catch{return null}let s=i.session_id?.trim();if(!s)return null;let a=`session-close:${createHash("sha256").update(`${e}\0${s}`).digest("hex").slice(0,24)}`,c={inputJson:n,sessionId:s,cleanupSharedState:t,executionId:o};try{de(e,s);}catch{}let u;try{u=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});let d=u.requestSessionClosure({receiptId:a,projectRoot:e,sessionId:s,payload:c}),l=u.getWorkByIdempotencyKey(a),m={status:d.state==="closed"||d.state==="closed_with_pending_work"?"completed":"accepted",receiptId:a,workState:l?.state??"pending",closureState:d.state,pendingWorkCount:d.pendingWorkCount,...l?.id?{workItemId:l.id}:{}};return p({event:"hook.session_end.completed",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:m.status==="completed"?"info":"debug",timestamp:Date.now(),data:{stage:"enqueue",...m}}),m}catch(d){if(!r)throw d;return te(e,{receiptId:a,...c}),p({event:"hook.session_end.degraded",identity:{projectRoot:e,sessionId:s,executionId:o,terminalReceipt:a},level:"warn",timestamp:Date.now(),data:{stage:"enqueue",reason:Mt(d),fallback:"durable_spool"}}),{status:"accepted",receiptId:a,workState:"spooled",closureState:"closing",pendingWorkCount:1}}finally{u?.close();}}if(process.argv[1]?.endsWith("session-end")||process.argv[1]?.endsWith("session-end.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=Ot(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),1e4).unref();}var E=1,qt="memory-snapshot-v1.json",Ht=512*1024,fe=256*1024,ge=2e3,Ut=500,zt=10,Bt=240,Jt=300*1e3,Wt=720*60*60*1e3,Gt=2147483647;function Kt(n){return n.currentUid===void 0?{ownerSafe:true,modeSafe:true}:{ownerSafe:n.ownerUid===n.currentUid,modeSafe:(n.mode&18)===0}}function b(n){return resolve(n)}function S(n){return createHash("sha256").update(b(n)).digest("hex").slice(0,16)}function Vt(n,e={}){let t=S(n),o=e.stateRoot?join(e.stateRoot,t):getProjectStateDir(b(n));return join(o,qt)}function Yt(n,e){let o=(n instanceof Error?n.message:"").replace(/[\r\n\t]+/gu," ").trim().slice(0,160);return o?`${e}:${o}`:e}function N(n,e){return Array.isArray(n)&&n.length<=e&&n.every(t=>typeof t=="string"&&t.length>0&&t.length<=512)}function Xt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.id=="string"&&e.id.length>0&&e.id.length<=512&&typeof e.kind=="string"&&e.kind.length>0&&e.kind.length<=128&&(e.family===void 0||typeof e.family=="string"&&e.family.length>0&&e.family.length<=256)&&(e.entity===void 0||typeof e.entity=="string"&&e.entity.length>0&&e.entity.length<=256)&&N(e.memoryIds,100)&&(e.status==="withheld"||e.status==="resolved")&&(e.summary===void 0||typeof e.summary=="string"&&e.summary.length<=2e3)}function Zt(n){if(!n||typeof n!="object"||Array.isArray(n))return false;let e=n;return typeof e.reason=="string"&&e.reason.length>0&&e.reason.length<=512&&(e.stale===void 0||typeof e.stale=="boolean")}function ye(n,e,t){if(!n||typeof n!="object"||Array.isArray(n))return null;let o=n,r=b(e),i=S(r),s=o.generation===void 0?0:o.generation;return o.version!==E||o.projectRoot!==r||o.projectHash!==i||typeof o.markdown!="string"||Buffer.byteLength(o.markdown,"utf8")>fe||!N(o.memoryIds,ge)||!Array.isArray(o.conflicts)||o.conflicts.length>Ut||!o.conflicts.every(Xt)||typeof o.generatedAt!="number"||!Number.isFinite(o.generatedAt)||o.generatedAt<0||o.generatedAt>t+Jt||!Number.isInteger(s)||s<0||s>Gt||!["ready","pending","degraded","disabled"].includes(String(o.status))||o.degradation!==void 0&&!Zt(o.degradation)?null:{...o,generation:s}}function Qt(n,e,t,o,r=0){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:o,generation:r,status:e,degradation:{reason:t}}}function en(n,e={}){let t=e.now??Date.now(),o=Vt(n,e),r;try{r=openSync(o,constants.O_RDONLY|constants.O_NOFOLLOW);let i=fstatSync(r);if(!i.isFile()||i.size<=0||i.size>Ht)throw new Error("cache_size_invalid");let s=Kt({...typeof process.getuid=="function"?{currentUid:process.getuid()}:{},ownerUid:i.uid,mode:i.mode});if(!s.ownerSafe)throw new Error("cache_owner_invalid");if(!s.modeSafe)throw new Error("cache_permissions_unsafe");let a=JSON.parse(readFileSync(r,"utf8")),c=ye(a,n,t);if(!c)throw new Error("cache_schema_invalid");return c.status==="ready"&&t-c.generatedAt>Wt?{snapshot:{...c,status:"degraded",degradation:{reason:"cache_stale",stale:!0}},source:"cache",valid:!0,stale:!0}:{snapshot:c,source:"cache",valid:!0,stale:!1}}catch(i){let a=i.code==="ENOENT";return {snapshot:Qt(n,a?"pending":"degraded",a?"cache_missing":Yt(i,"cache_invalid"),t),source:"none",valid:false,stale:false}}finally{if(r!==void 0)try{closeSync(r);}catch{}}}function tn(n){if(!n)return true;try{return JSON.parse(readFileSync(n,"utf8")).sessionStart?.injectMemories??!0}catch{return true}}function nn(n,e,t){if(!e.trim())return null;try{let o=JSON.parse(e);if(o.status!=="ok"&&o.status!=="degraded")return null;if(o.enabled===!1){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:"",memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"disabled"}}let r=ye(o.snapshot,n,t);if(r)return r;if(o.status==="ok"&&typeof o.markdown=="string"&&o.markdown.length>0&&Buffer.byteLength(o.markdown,"utf8")<=fe){let i=b(n);return {version:E,projectRoot:i,projectHash:S(i),markdown:o.markdown,memoryIds:N(o.memoryIds,ge)?o.memoryIds:[],conflicts:[],generatedAt:t,generation:0,status:"ready"}}}catch{}return null}function L(n,e){return [...(n??e).replace(/[\r\n\t|]+/gu," ").trim()||e].slice(0,Bt).join("")}function on(n){if(n.length===0)return "";let e=n.slice(0,zt),t=e.map(o=>{let r=L(o.family,"unknown"),i=L(o.entity,"unknown"),s=L(o.summary,"Explicit choice required.");return `- family=${r}; entity=${i}; status=${o.status}; summary=${s}`});return n.length>e.length&&t.push(`- ${n.length-e.length} additional conflict(s) omitted from SessionStart output.`),`## Withheld preference conflicts (${n.length})
11
11
  ${t.join(`
12
- `)}`}function en(n){let e=n.now??Date.now();if(Yt(n.configPath)===false)return "";let t=Zt(n.projectRoot,n.daemonResponse??"",e),o=t?{snapshot:t,source:"daemon"}:Xt(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:r}=o;if(r.status==="disabled")return `## Project memory
13
- DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=Qt(r.conflicts);return r.markdown?[r.markdown,c,a].filter(Boolean).join(`
12
+ `)}`}function rn(n){let e=n.now??Date.now();if(tn(n.configPath)===false)return "";let t=nn(n.projectRoot,n.daemonResponse??"",e),o=t?{snapshot:t,source:"daemon"}:en(n.projectRoot,{...n.cacheOptions,now:e}),{snapshot:r}=o;if(r.status==="disabled")return `## Project memory
13
+ DevFlow memory snapshot=pending; source=${o.source}; reason=previous_snapshot_disabled. Memory availability is not yet known; do not conclude that the project has no memories.`;let i=new Date(r.generatedAt).toISOString(),s=r.degradation?.reason?`; reason=${r.degradation.reason}`:"",a=`DevFlow memory snapshot=${r.status}; source=${o.source}; generatedAt=${i}${s}.`,c=on(r.conflicts);return r.markdown?[r.markdown,c,a].filter(Boolean).join(`
14
14
  `):["## Project memory",c,`${a} Memory availability is not yet known; do not conclude that the project has no memories.`].filter(Boolean).join(`
15
- `)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(en({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}function ye(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call mcp__devflow__memory_commit_turn with evidence-bound candidates, or mcp__devflow__memory_skip_turn with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function he(n){let e=ie({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{sn(n.runtimeStore,n.sessionId,t);let o=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),r=o?t.markMemoryTurnStopPrompted(o.turnId):!1,i=[];e&&i.push(e.reason),o&&r&&i.push(ye(o)),o&&!r&&on(t,o.turnId)&&rn(P(n.transcriptPath))&&i.push(`DevFlow explicit memory ${o.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=t.listSessionObligations(n.projectRoot,n.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?"Call mcp__devflow__memory_decide_turn using the canonical turn ID.":c.kind==="evidence_contract"?c.payload.subtype==="policy_verification"?`Complete the required project verification: ${String(c.payload.command??c.payload.verificationKind??"unknown command")}.`:"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
15
+ `)}if(process.env.DEVFLOW_MEMORY_SNAPSHOT_CLI==="1"){let[,,n,e,t]=process.argv;n!=="session-start"||!e?process.exitCode=2:process.stdout.write(rn({projectRoot:e,configPath:t,daemonResponse:process.env.DEVFLOW_MEMORY_RESPONSE}));}function he(n){return `DevFlow memory decision required for ${n.turnId}. Before the final response, semantically decide whether this turn contains durable project knowledge. Call mcp__devflow__memory_commit_turn with evidence-bound candidates, or mcp__devflow__memory_skip_turn with a concrete reason. Do not claim memory success without a canonical receipt. For candidates, copy exact evidenceSpans from this user prompt, preserve package names, flags, versions, paths, and identifiers, and provide subject, predicate, value, polarity, and entities when known. To replace or retire an existing fact, provide operation=supersede or operation=retire plus referencedFactIds from the canonical memory receipt; aliases and entity names are not fact identity. Do not save assistant echoes, task narration, retries, or unverified guesses. Express a change from an old choice as the new durable value. If the decision tool remains unavailable, explicitly state that the memory was not saved.`}function Ie(n){let e=ie({projectRoot:n.projectRoot,sessionId:n.sessionId,transcriptPath:n.transcriptPath,runtimeStore:n.runtimeStore}),t=openGlobalDevFlowDatabase(void 0,{busyTimeoutMs:50});try{ln(n.runtimeStore,n.sessionId,t);let o=t.getPendingMemoryTurn(n.projectRoot,n.sessionId),r=o?t.markMemoryTurnStopPrompted(o.turnId):!1,i=[];e&&i.push(e.reason),o&&r&&i.push(he(o)),o&&!r&&cn(t,o.turnId)&&dn(P(n.transcriptPath))&&i.push(`DevFlow explicit memory ${o.turnId} still has no canonical receipt. Remove the memory-success claim and tell the user that the memory was not saved, or complete the pending turn.`);let a=t.listSessionObligations(n.projectRoot,n.sessionId,["open"]).map(c=>({obligationId:c.obligationId,kind:c.kind,action:c.kind==="memory_decision"?"Call mcp__devflow__memory_decide_turn using the canonical turn ID.":c.kind==="evidence_contract"?c.payload.subtype==="policy_verification"?`Complete the required project verification: ${String(c.payload.command??c.payload.verificationKind??"unknown command")}.`:"Return a final answer that satisfies the canonical evidence contract.":"Allow SessionEnd durable finalization to complete.",canonicalInput:c.kind==="memory_decision"&&c.turnId?{turnId:c.turnId}:void 0}));return i.length>0?{decision:"block_once",unresolved:a,additionalContext:["DevFlow has unresolved terminal obligations. Complete all actions below before stopping.",...i].join(`
16
16
 
17
- `)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{t.close();}}function on(n,e){return !!n.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${e}`)}function rn(n){if(!n)return false;let e=n.normalize("NFKC").replace(/\s+/gu," ");return /(?:未|没有|无法|失败|暂未|尚未).{0,24}(?:记住|记下|记录|保存|持久化|回执)|(?:memory|receipt).{0,24}(?:failed|missing|pending|degraded|not saved)|status=(?:pending|degraded|rejected|failed)/iu.test(e)?false:/(?:已|已经|成功).{0,20}(?:记住|记下|记录|保存|持久化)|跨会话生效|(?:memory|preference).{0,20}(?:saved|remembered|persisted)|status=(?:accepted|committed)/iu.test(e)}function sn(n,e,t){let o=n.get(e);if(o){for(let r of o.evidenceObligations)t.upsertSessionObligation({obligationId:`evidence:${r.obligationId}`,projectRoot:o.projectRoot,sessionId:e,executionId:o.executionId,kind:"evidence_contract",state:"open",payload:{contract:r.contract,runtimeObligationId:r.obligationId},createdAt:r.promptedAt,updatedAt:o.lastActivityAt});for(let r of o.evidenceOutcomes){let i=`evidence:${r.obligationId}`,s=t.getSessionObligation(o.projectRoot,e,i);if(!s||s.state!=="open"&&!(s.state==="degraded"&&r.status==="resolved"))continue;let a=r.status==="resolved"?`evidence-receipt:${createHash("sha256").update(`${r.obligationId}\0${r.completedAt}\0${r.attempt}`).digest("hex").slice(0,24)}`:void 0;t.resolveSessionObligation({projectRoot:o.projectRoot,sessionId:e,obligationId:i,state:r.status==="resolved"?"satisfied":"degraded",receiptId:a,reason:r.reason,resolvedAt:r.completedAt});}}}async function cn(n,e=_()){let t;try{t=JSON.parse(n);}catch{return null}let o=t.session_id?.trim();if(!o)return null;let r=new I(e),i=he({projectRoot:e,sessionId:o,transcriptPath:t.transcript_path,stopHookActive:t.stop_hook_active===true,runtimeStore:r});if(i.decision==="block_once")return p({event:"hook.stop.degraded",identity:{projectRoot:e,sessionId:o},level:"warn",timestamp:Date.now(),data:{decision:"block_once",unresolved:i.unresolved.map(a=>a.obligationId)}}),{decision:"block",reason:i.additionalContext};let s=r.completeExecution(o);if(s?.executionId){let a=openGlobalDevFlowDatabase();try{let c=a.listSessionMemoryTurnsForReconciliation(e,o),u=new Map(a.listLatestTaskIntentArtifacts(e,o).map(d=>[d.turnId,d]));for(let d of c){let l=u.get(d.turnId);!l||d.status==="pending"||F({artifact:l,memoryStatus:d.status,memoryReceiptId:d.receiptId,reason:"stop_obligations_satisfied"});}a.reconcileSkillExecution(s.executionId,"completed",Date.now(),{...de(c),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision}),a.deleteContextReceipt(e,o,s.executionId);}finally{a.close();}}return k(`/api/telemetry/sessions/${encodeURIComponent(o)}/tick`,{timestamp:Date.now()},{fallbackReason:"stop_tick_already_local"}),p({event:"hook.stop.completed",identity:{projectRoot:e,sessionId:o,executionId:s?.executionId},level:"info",timestamp:Date.now(),data:{decision:i.decision,unresolvedCount:i.unresolved.length}}),null}if(process.argv[1]?.endsWith("stop")||process.argv[1]?.endsWith("stop.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=await cn(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),4e3).unref();}export{cn as handleStop};
17
+ `)}:a.length>0?{decision:"degrade",unresolved:a,additionalContext:"DevFlow terminal obligations remain unresolved after their one-shot correction budget."}:{decision:"allow",unresolved:[]}}finally{t.close();}}function cn(n,e){return !!n.getWorkByIdempotencyKey(`memory-turn:commit_explicit:${e}`)}function dn(n){if(!n)return false;let e=n.normalize("NFKC").replace(/\s+/gu," ");return /(?:未|没有|无法|失败|暂未|尚未).{0,24}(?:记住|记下|记录|保存|持久化|回执)|(?:memory|receipt).{0,24}(?:failed|missing|pending|degraded|not saved)|status=(?:pending|degraded|rejected|failed)/iu.test(e)?false:/(?:已|已经|成功).{0,20}(?:记住|记下|记录|保存|持久化)|跨会话生效|(?:memory|preference).{0,20}(?:saved|remembered|persisted)|status=(?:accepted|committed)/iu.test(e)}function ln(n,e,t){let o=n.get(e);if(o){for(let r of o.evidenceObligations)t.upsertSessionObligation({obligationId:`evidence:${r.obligationId}`,projectRoot:o.projectRoot,sessionId:e,executionId:o.executionId,kind:"evidence_contract",state:"open",payload:{contract:r.contract,runtimeObligationId:r.obligationId},createdAt:r.promptedAt,updatedAt:o.lastActivityAt});for(let r of o.evidenceOutcomes){let i=`evidence:${r.obligationId}`,s=t.getSessionObligation(o.projectRoot,e,i);if(!s||s.state!=="open"&&!(s.state==="degraded"&&r.status==="resolved"))continue;let a=r.status==="resolved"?`evidence-receipt:${createHash("sha256").update(`${r.obligationId}\0${r.completedAt}\0${r.attempt}`).digest("hex").slice(0,24)}`:void 0;t.resolveSessionObligation({projectRoot:o.projectRoot,sessionId:e,obligationId:i,state:r.status==="resolved"?"satisfied":"degraded",receiptId:a,reason:r.reason,resolvedAt:r.completedAt});}}}async function mn(n,e=_()){let t;try{t=JSON.parse(n);}catch{return null}let o=t.session_id?.trim();if(!o)return null;let r=new I(e),i=Ie({projectRoot:e,sessionId:o,transcriptPath:t.transcript_path,stopHookActive:t.stop_hook_active===true,runtimeStore:r});if(i.decision==="block_once")return p({event:"hook.stop.degraded",identity:{projectRoot:e,sessionId:o},level:"warn",timestamp:Date.now(),data:{decision:"block_once",unresolved:i.unresolved.map(a=>a.obligationId)}}),{decision:"block",reason:i.additionalContext};let s=r.completeExecution(o);if(s?.executionId){let a=openGlobalDevFlowDatabase();try{let c=a.listSessionMemoryTurnsForReconciliation(e,o),u=new Map(a.listLatestTaskIntentArtifacts(e,o).map(d=>[d.turnId,d]));for(let d of c){let l=u.get(d.turnId);!l||d.status==="pending"||F({artifact:l,memoryStatus:d.status,memoryReceiptId:d.receiptId,reason:"stop_obligations_satisfied"});}a.reconcileSkillExecution(s.executionId,"completed",Date.now(),{...le(c),evidenceDegradations:s.evidenceDegradations,evidenceContractOutcomes:s.evidenceOutcomes,unresolvedObligations:i.unresolved,terminalState:i.decision}),a.deleteContextReceipt(e,o,s.executionId);}finally{a.close();}}return k(`/api/telemetry/sessions/${encodeURIComponent(o)}/tick`,{timestamp:Date.now()},{fallbackReason:"stop_tick_already_local"}),p({event:"hook.stop.completed",identity:{projectRoot:e,sessionId:o,executionId:s?.executionId},level:"info",timestamp:Date.now(),data:{decision:i.decision,unresolvedCount:i.unresolved.length}}),null}if(process.argv[1]?.endsWith("stop")||process.argv[1]?.endsWith("stop.js")){let n=console.log.bind(console);console.log=console.error.bind(console),console.info=console.error.bind(console);let e="";process.stdin.setEncoding("utf8"),process.stdin.on("data",t=>{e+=t;}),process.stdin.on("end",async()=>{let t=await mn(e.trim()||process.argv[2]||"");t&&n(JSON.stringify(t)),process.exit(0);}),process.stdin.on("error",()=>process.exit(0)),setTimeout(()=>process.exit(0),4e3).unref();}export{mn as handleStop};
@@ -12,13 +12,14 @@ required_mcp_tools:
12
12
  - delivery_resume
13
13
  - delivery_advance
14
14
  - delivery_retry_task
15
+ - delivery_import_external_change
15
16
  - delivery_export
16
17
  - delivery_cancel
17
18
  ---
18
19
 
19
20
  <HARD-GATE>
20
21
  收到 devflow:delivery 时,必须先调用以下 MCP 工具之一:
21
- delivery_status / delivery_create_case / delivery_answer / delivery_revise / delivery_compare_options / delivery_approve / delivery_reject / delivery_resume / delivery_advance / delivery_retry_task / delivery_export / delivery_cancel
22
+ delivery_status / delivery_create_case / delivery_answer / delivery_revise / delivery_compare_options / delivery_approve / delivery_reject / delivery_resume / delivery_advance / delivery_retry_task / delivery_import_external_change / delivery_export / delivery_cancel
22
23
  </HARD-GATE>
23
24
 
24
25
  ## MANDATORY FIRST STEP - Skill Registration
@@ -26,7 +27,7 @@ delivery_status / delivery_create_case / delivery_answer / delivery_revise / del
26
27
  > **IMPORTANT: Before ANY other action, execute the registration command below. This is NON-NEGOTIABLE.**
27
28
 
28
29
  ```bash
29
- mkdir -p ~/.devflow && echo '{"name":"devflow:delivery","required_mcp_tools":["delivery_status","delivery_create_case","delivery_answer","delivery_revise","delivery_compare_options","delivery_approve","delivery_reject","delivery_resume","delivery_advance","delivery_retry_task","delivery_export","delivery_cancel"],"description":"devflow:delivery skill","registeredAt":'"$(date +%s)000"'}' > ~/.devflow/current-skill.json
30
+ mkdir -p ~/.devflow && echo '{"name":"devflow:delivery","required_mcp_tools":["delivery_status","delivery_create_case","delivery_answer","delivery_revise","delivery_compare_options","delivery_approve","delivery_reject","delivery_resume","delivery_advance","delivery_retry_task","delivery_import_external_change","delivery_export","delivery_cancel"],"description":"devflow:delivery skill","registeredAt":'"$(date +%s)000"'}' > ~/.devflow/current-skill.json
30
31
  ```
31
32
 
32
33
  After registration, you **MUST** use ONLY these MCP tools for all work in this skill:
@@ -40,6 +41,7 @@ After registration, you **MUST** use ONLY these MCP tools for all work in this s
40
41
  - `mcp__devflow__delivery_resume`
41
42
  - `mcp__devflow__delivery_advance`
42
43
  - `mcp__devflow__delivery_retry_task`
44
+ - `mcp__devflow__delivery_import_external_change`
43
45
  - `mcp__devflow__delivery_export`
44
46
  - `mcp__devflow__delivery_cancel`
45
47
 
@@ -66,17 +68,21 @@ rm -f ~/.devflow/current-skill.json ~/.devflow/current-execution-id
66
68
  - 只有用户明确同意时才能调用 `mcp__devflow__delivery_approve`;不得代替用户批准。
67
69
  - `mcp__devflow__delivery_advance` 用于推进已满足的状态,`mcp__devflow__delivery_resume` 只恢复已经具备运行条件的 gate 或 task。
68
70
  - 失败任务只通过 `mcp__devflow__delivery_retry_task` 重试;取消和导出分别使用 `mcp__devflow__delivery_cancel` 与 `mcp__devflow__delivery_export`。
71
+ - Claude 在当前工作区产生的修改不是 Delivery 输出;只能先调用 `mcp__devflow__delivery_import_external_change`,由系统校验 base/candidate、允许文件、context receipt 和验证证据后再进入 integration。
69
72
 
70
73
  ## 可用操作
71
74
 
72
75
  - 澄清和设计:`delivery_answer`、`delivery_revise`、`delivery_compare_options`
73
76
  - Gate 决策:`delivery_approve`、`delivery_reject`
74
77
  - 状态和执行:`delivery_status`、`delivery_advance`、`delivery_resume`、`delivery_retry_task`
78
+ - 外部变更:`delivery_import_external_change`
75
79
  - 交付收尾:`delivery_export`、`delivery_cancel`
76
80
 
77
81
  ## 错误处理
78
82
 
79
83
  - MCP 返回 `ok: false` 时,该操作已经失败。向用户呈现 `error.code` 和 `error.message`,不得把 transport 成功误报为交付成功。
84
+ - `error.retryable=false` 时不得自动重试;`error.recoveryAction` 是下一步建议,不是已完成的动作。
85
+ - 遇到 `HELD`、`WORKER_UNAVAILABLE`、`REQUIRED_CONTEXT_MISSING` 或 producer/stale 警告时,先刷新 `delivery_status` 并保留阻塞状态;不得通过普通 Write/Edit/Bash/git commit 绕过 Delivery authority。
80
86
  - 遇到 `STALE_INTERACTION_TURN`、`MISSING_PREREQUISITE` 或 `INVALID_TRANSITION` 时,先调用 `mcp__devflow__delivery_status` 刷新案件状态;只有新的 `nextActions` 明确允许时才继续。
81
87
  - 用户拒绝审批,或遇到 `UNAUTHORIZED_ROLE`、权限失败、`PROJECT_ROOT_MISMATCH` 时不得自动重试;保留案件当前状态并请求用户处理。
82
88
  - 不通过更换 actor、project root、turn、context receipt 或幂等键来规避失败。
@@ -13,13 +13,13 @@ if [ -f "$CLIENT_JS" ]; then
13
13
  "$DEVFLOW_NODE" "$CLIENT_JS" pre-tool-use || {
14
14
  echo '[devflow] hook-client failed, trying fallback' >&2
15
15
  if [ -f "$FALLBACK_JS" ]; then
16
- DEVFLOW_HOOK_DEGRADED=1 "$DEVFLOW_NODE" "$FALLBACK_JS" || echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","additionalContext":"WARNING: DevFlow is in degraded mode (daemon unreachable). Run devflow doctor for details."}}'
16
+ DEVFLOW_HOOK_DEGRADED=1 "$DEVFLOW_NODE" "$FALLBACK_JS" || echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"DevFlow hook unavailable; writes are blocked until Delivery authority can be verified."}}'
17
17
  else
18
- echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","additionalContext":"WARNING: DevFlow is in degraded mode (daemon unreachable). Run devflow doctor for details."}}'
18
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"DevFlow hook unavailable; writes are blocked until Delivery authority can be verified."}}'
19
19
  fi
20
20
  }
21
21
  elif [ -f "$FALLBACK_JS" ]; then
22
- DEVFLOW_HOOK_DEGRADED=1 "$DEVFLOW_NODE" "$FALLBACK_JS" || echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","additionalContext":"WARNING: DevFlow is in degraded mode (daemon unavailable). Run devflow doctor for details."}}'
22
+ DEVFLOW_HOOK_DEGRADED=1 "$DEVFLOW_NODE" "$FALLBACK_JS" || echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"DevFlow hook unavailable; writes are blocked until Delivery authority can be verified."}}'
23
23
  else
24
- echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"allow","additionalContext":"WARNING: DevFlow is in degraded mode (daemon unavailable). Run devflow doctor for details."}}'
24
+ echo '{"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny","permissionDecisionReason":"DevFlow hook unavailable; writes are blocked until Delivery authority can be verified."}}'
25
25
  fi
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/claude-code-plugin",
3
- "version": "0.18.10",
3
+ "version": "0.18.12",
4
4
  "description": "Claude Code hooks and skills for the DevFlow development intelligence runtime.",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -12,20 +12,20 @@
12
12
  "verify:runtime-dependencies": "node --import tsx scripts/verify-runtime-dependencies.ts"
13
13
  },
14
14
  "dependencies": {
15
- "@devflow-tools/benchmark": "0.18.10",
16
- "@devflow-tools/context-engine": "0.18.10",
17
- "@devflow-tools/database": "0.18.10",
18
- "@devflow-tools/mcp-server": "0.18.10",
19
- "@devflow-tools/memory-engine": "0.18.10",
20
- "@devflow-tools/sdk": "0.18.10",
21
- "@devflow-tools/semantic-engine": "0.18.10",
22
- "@devflow-tools/server": "0.18.10",
23
- "@devflow-tools/task-runtime": "0.18.10",
24
- "@devflow-tools/telemetry": "0.18.10",
25
- "@devflow-tools/workflow-engine": "0.18.10"
15
+ "@devflow-tools/benchmark": "0.18.12",
16
+ "@devflow-tools/context-engine": "0.18.12",
17
+ "@devflow-tools/database": "0.18.12",
18
+ "@devflow-tools/mcp-server": "0.18.12",
19
+ "@devflow-tools/memory-engine": "0.18.12",
20
+ "@devflow-tools/sdk": "0.18.12",
21
+ "@devflow-tools/semantic-engine": "0.18.12",
22
+ "@devflow-tools/server": "0.18.12",
23
+ "@devflow-tools/task-runtime": "0.18.12",
24
+ "@devflow-tools/telemetry": "0.18.12",
25
+ "@devflow-tools/workflow-engine": "0.18.12"
26
26
  },
27
27
  "devDependencies": {
28
- "@devflow-tools/devflow": "0.18.10"
28
+ "@devflow-tools/devflow": "0.18.12"
29
29
  },
30
30
  "allowScripts": {
31
31
  "better-sqlite3@12.11.1": true,
@@ -50,7 +50,7 @@
50
50
  "hooks",
51
51
  "skills"
52
52
  ],
53
- "gitHead": "940c6c004c0ebb59abad3da9bc67137fa2d2a666",
53
+ "gitHead": "4bef753de830e4e881bd150c9b090ab0953139c1",
54
54
  "license": "MIT",
55
55
  "repository": {
56
56
  "type": "git",
@@ -19,17 +19,21 @@ description: 通过可审计 Delivery Line 将需求推进到验证完成的 int
19
19
  - 只有用户明确同意时才能调用 `mcp__devflow__delivery_approve`;不得代替用户批准。
20
20
  - `mcp__devflow__delivery_advance` 用于推进已满足的状态,`mcp__devflow__delivery_resume` 只恢复已经具备运行条件的 gate 或 task。
21
21
  - 失败任务只通过 `mcp__devflow__delivery_retry_task` 重试;取消和导出分别使用 `mcp__devflow__delivery_cancel` 与 `mcp__devflow__delivery_export`。
22
+ - Claude 在当前工作区产生的修改不是 Delivery 输出;只能先调用 `mcp__devflow__delivery_import_external_change`,由系统校验 base/candidate、允许文件、context receipt 和验证证据后再进入 integration。
22
23
 
23
24
  ## 可用操作
24
25
 
25
26
  - 澄清和设计:`delivery_answer`、`delivery_revise`、`delivery_compare_options`
26
27
  - Gate 决策:`delivery_approve`、`delivery_reject`
27
28
  - 状态和执行:`delivery_status`、`delivery_advance`、`delivery_resume`、`delivery_retry_task`
29
+ - 外部变更:`delivery_import_external_change`
28
30
  - 交付收尾:`delivery_export`、`delivery_cancel`
29
31
 
30
32
  ## 错误处理
31
33
 
32
34
  - MCP 返回 `ok: false` 时,该操作已经失败。向用户呈现 `error.code` 和 `error.message`,不得把 transport 成功误报为交付成功。
35
+ - `error.retryable=false` 时不得自动重试;`error.recoveryAction` 是下一步建议,不是已完成的动作。
36
+ - 遇到 `HELD`、`WORKER_UNAVAILABLE`、`REQUIRED_CONTEXT_MISSING` 或 producer/stale 警告时,先刷新 `delivery_status` 并保留阻塞状态;不得通过普通 Write/Edit/Bash/git commit 绕过 Delivery authority。
33
37
  - 遇到 `STALE_INTERACTION_TURN`、`MISSING_PREREQUISITE` 或 `INVALID_TRANSITION` 时,先调用 `mcp__devflow__delivery_status` 刷新案件状态;只有新的 `nextActions` 明确允许时才继续。
34
38
  - 用户拒绝审批,或遇到 `UNAUTHORIZED_ROLE`、权限失败、`PROJECT_ROOT_MISMATCH` 时不得自动重试;保留案件当前状态并请求用户处理。
35
39
  - 不通过更换 actor、project root、turn、context receipt 或幂等键来规避失败。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devflow-tools/cli",
3
- "version": "0.18.10",
3
+ "version": "0.18.12",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "devflow": "./bin/devflow.cjs"
@@ -14,38 +14,38 @@
14
14
  },
15
15
  "dependencies": {
16
16
  "@colbymchenry/codegraph": "^1.1.1",
17
- "@devflow-tools/adapters": "0.18.10",
18
- "@devflow-tools/benchmark": "0.18.10",
19
- "@devflow-tools/context-engine": "0.18.10",
20
- "@devflow-tools/database": "0.18.10",
21
- "@devflow-tools/delivery-line": "0.18.10",
22
- "@devflow-tools/knowledge-engine": "0.18.10",
23
- "@devflow-tools/mcp-server": "0.18.10",
24
- "@devflow-tools/memory-engine": "0.18.10",
25
- "@devflow-tools/plugin-animation": "0.18.10",
26
- "@devflow-tools/plugin-css": "0.18.10",
27
- "@devflow-tools/plugin-docker": "0.18.10",
28
- "@devflow-tools/plugin-electron": "0.18.10",
29
- "@devflow-tools/plugin-git": "0.18.10",
30
- "@devflow-tools/plugin-graphql": "0.18.10",
31
- "@devflow-tools/plugin-nest": "0.18.10",
32
- "@devflow-tools/plugin-nextjs": "0.18.10",
33
- "@devflow-tools/plugin-performance": "0.18.10",
34
- "@devflow-tools/plugin-react": "0.18.10",
35
- "@devflow-tools/plugin-tailwind": "0.18.10",
36
- "@devflow-tools/plugin-taro": "0.18.10",
37
- "@devflow-tools/plugin-ui-layout": "0.18.10",
38
- "@devflow-tools/plugin-vue": "0.18.10",
39
- "@devflow-tools/sdk": "0.18.10",
40
- "@devflow-tools/server": "0.18.10",
41
- "@devflow-tools/telemetry": "0.18.10",
42
- "@devflow-tools/workflow-engine": "0.18.10",
17
+ "@devflow-tools/adapters": "0.18.12",
18
+ "@devflow-tools/benchmark": "0.18.12",
19
+ "@devflow-tools/context-engine": "0.18.12",
20
+ "@devflow-tools/database": "0.18.12",
21
+ "@devflow-tools/delivery-line": "0.18.12",
22
+ "@devflow-tools/knowledge-engine": "0.18.12",
23
+ "@devflow-tools/mcp-server": "0.18.12",
24
+ "@devflow-tools/memory-engine": "0.18.12",
25
+ "@devflow-tools/plugin-animation": "0.18.12",
26
+ "@devflow-tools/plugin-css": "0.18.12",
27
+ "@devflow-tools/plugin-docker": "0.18.12",
28
+ "@devflow-tools/plugin-electron": "0.18.12",
29
+ "@devflow-tools/plugin-git": "0.18.12",
30
+ "@devflow-tools/plugin-graphql": "0.18.12",
31
+ "@devflow-tools/plugin-nest": "0.18.12",
32
+ "@devflow-tools/plugin-nextjs": "0.18.12",
33
+ "@devflow-tools/plugin-performance": "0.18.12",
34
+ "@devflow-tools/plugin-react": "0.18.12",
35
+ "@devflow-tools/plugin-tailwind": "0.18.12",
36
+ "@devflow-tools/plugin-taro": "0.18.12",
37
+ "@devflow-tools/plugin-ui-layout": "0.18.12",
38
+ "@devflow-tools/plugin-vue": "0.18.12",
39
+ "@devflow-tools/sdk": "0.18.12",
40
+ "@devflow-tools/server": "0.18.12",
41
+ "@devflow-tools/telemetry": "0.18.12",
42
+ "@devflow-tools/workflow-engine": "0.18.12",
43
43
  "@inquirer/prompts": "^7.10.1",
44
44
  "chalk": "^5.3.0",
45
45
  "commander": "^12.0.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@devflow-tools/devflow": "0.18.10",
48
+ "@devflow-tools/devflow": "0.18.12",
49
49
  "typescript": "^5.5.0",
50
50
  "vitest": "^2.0.0"
51
51
  },
@@ -53,7 +53,7 @@
53
53
  "dist",
54
54
  "bin"
55
55
  ],
56
- "gitHead": "940c6c004c0ebb59abad3da9bc67137fa2d2a666",
56
+ "gitHead": "4bef753de830e4e881bd150c9b090ab0953139c1",
57
57
  "description": "Command-line interface for DevFlow development intelligence and diagnostics.",
58
58
  "license": "MIT",
59
59
  "repository": {