@popmelt.com/core 0.8.7 → 0.8.9

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.
@@ -216,12 +216,15 @@ type VerificationTarget = {
216
216
  entityType: 'decision' | 'implementation_attempt' | 'model_entry';
217
217
  entityId: MemoryId;
218
218
  };
219
+ /** @deprecated Retained only so existing memory journals remain readable. */
219
220
  type EvalSpecState = 'draft' | 'active' | 'retired';
221
+ /** @deprecated Retained only so existing memory journals remain readable. */
220
222
  type EvalDependency = {
221
223
  kind: 'model_path' | 'source_file' | 'route' | 'subject';
222
224
  value: string;
223
225
  subjectId?: MemoryId;
224
226
  };
227
+ /** @deprecated Retained only so existing memory journals remain readable. */
225
228
  type EvalScenario = {
226
229
  id: string;
227
230
  label?: string;
@@ -244,6 +247,7 @@ type EvalScenario = {
244
247
  value?: string;
245
248
  }>;
246
249
  };
250
+ /** @deprecated Retained only so existing memory journals remain readable. */
247
251
  type EvalSpecRecord = Provenance & {
248
252
  recordType: 'eval_spec';
249
253
  state: EvalSpecState;
@@ -283,7 +287,7 @@ type VerificationAttemptRecord = Provenance & {
283
287
  targets: VerificationTarget[];
284
288
  summary?: string;
285
289
  evidenceIds: MemoryId[];
286
- /** Compact presentation data for an eval run; raw output remains an artifact/thread detail. */
290
+ /** @deprecated Historical presentation data retained for journal compatibility. */
287
291
  evalRun?: {
288
292
  id: string;
289
293
  threadId?: string;
@@ -1 +1 @@
1
- import{createHash as Me}from"crypto";import{readFile as Le,readdir as Pe,realpath as Be}from"fs/promises";import{join as X,relative as De}from"path";var Ae=/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function Se(n){return Ae.test(n)}function Re(n){return{valid:!n.some(e=>e.severity==="error"),issues:n}}function d(n,e,i,m){n.push({path:e,code:i,message:m,severity:"error"})}function re(n,e,i,m){n.push({path:e,code:i,message:m,severity:"warning"})}function $(n,e,i){Se(i)||d(n,e,"invalid_uuid_v7","Canonical IDs must be UUIDv7 values.")}function x(n,e,i){(!i||Number.isNaN(Date.parse(i)))&&d(n,e,"invalid_timestamp","Timestamps must be parseable ISO-8601 strings.")}function D(n,e,i,m=!1){m&&i.level==="contributor"&&d(n,`${e}.level`,"insufficient_authority","Contributors cannot accept or change normative product truth."),i.level==="delegate"&&!i.grantId&&d(n,`${e}.grantId`,"missing_authority_grant","Delegate authority must reference the grant used for this action.")}var Ee={observation:new Set(["null->open","open->resolved","open->dismissed","resolved->open","dismissed->open"]),proposal:new Set(["null->draft","draft->pending","pending->accepted","pending->rejected","pending->withdrawn","pending->deferred","deferred->pending"]),decision:new Set(["null->active","active->superseded","active->revoked"]),advisory_explanation:new Set(["null->emerging","null->testing","null->grounded","null->challenged","null->retired","emerging->testing","emerging->grounded","emerging->challenged","emerging->retired","testing->grounded","testing->challenged","testing->retired","grounded->challenged","grounded->retired","challenged->testing","challenged->retired"]),implementation_attempt:new Set(["null->planned","planned->in_progress","planned->abandoned","in_progress->completed","in_progress->failed","in_progress->abandoned"]),eval_spec:new Set(["null->draft","null->active","draft->active","draft->retired","active->retired"]),verification_attempt:new Set(["null->queued","queued->running","queued->cancelled","running->passed","running->failed","running->inconclusive","running->error","running->cancelled"]),freshness_signal:new Set(["null->open","open->resolved"])},we=new Set(["proposal:accepted","proposal:rejected","decision:superseded","decision:revoked"]);function xe(n,e,i){$(n,`${i}.id`,e.id),$(n,`${i}.projectId`,e.projectId),$(n,`${i}.participantId`,e.participantId),$(n,`${i}.entity.entityId`,e.entity.entityId),x(n,`${i}.createdAt`,e.createdAt),D(n,`${i}.authority`,e.authority);let m=Ee[e.entity.entityType],f=`${e.fromState??"null"}->${e.toState}`;m&&!m.has(f)&&d(n,i,"invalid_lifecycle_transition",`${e.entity.entityType} does not allow ${f}.`);let I=`${e.entity.entityType}:${e.toState}`;if(we.has(I)&&(D(n,`${i}.authority`,e.authority,!0),e.reason?.trim()||d(n,`${i}.reason`,"missing_normative_reason","Normative acceptance, rejection, supersession, and revocation require a reason.")),e.entity.entityType==="proposal"&&e.toState==="deferred"){let y=e.transitionContext;(y?.kind!=="proposal_deferral"||y.resurfaceWhen.length===0)&&d(n,`${i}.transitionContext`,"missing_deferral_policy","Deferred proposals require structured resurfacing conditions."),y?.resurfaceWhen.includes("after_date")&&!y.revisitAfter&&d(n,`${i}.transitionContext.revisitAfter`,"missing_revisit_date","after_date resurfacing requires revisitAfter."),y?.revisitAfter&&x(n,`${i}.transitionContext.revisitAfter`,y.revisitAfter)}}function ke(n,e,i,m){$(n,`${i}.id`,e.id),$(n,`${i}.projectId`,e.projectId),$(n,`${i}.participantId`,e.participantId),x(n,`${i}.createdAt`,e.createdAt),e.projectId!==m&&d(n,`${i}.projectId`,"project_mismatch","Record belongs to another project."),"subjects"in e&&e.subjects.length===0&&d(n,`${i}.subjects`,"missing_subject","Proposals and decisions need a subject."),"subjects"in e&&e.subjects.length>1&&!e.subjectSemantics?.trim()&&d(n,`${i}.subjectSemantics`,"missing_subject_semantics","Multi-subject claims must explain why the subjects are inseparable."),e.recordType==="proposal"&&e.origin.mode==="inferred"&&(!e.origin.sourceText||!e.origin.iterationId||!e.origin.inferredById)&&d(n,`${i}.origin`,"incomplete_inference_provenance","Inferred structure requires source text, iteration, and inferring participant."),e.recordType==="decision"&&(D(n,`${i}.authority`,e.authority,!0),e.claim.trim()||d(n,`${i}.claim`,"empty_claim","Accepted decisions require a claim.")),e.recordType==="authority_grant"&&e.level==="owner"&&re(n,`${i}.level`,"owner_grant_requires_policy_review","Owner grants are valid but should receive explicit policy review."),e.recordType==="advisory_explanation"&&((!e.statement.trim()||!e.rationale.trim())&&d(n,i,"incomplete_advisory_explanation","Advisory explanations need a statement and rationale."),x(n,`${i}.updatedAt`,e.updatedAt),e.subjectIds.length===0&&d(n,`${i}.subjectIds`,"missing_subject","Advisory explanations need a subject."),e.scope.values.some(f=>!f.trim())&&d(n,`${i}.scope.values`,"empty_scope_value","Advisory scope values cannot be empty."),e.concreteBindings.forEach((f,I)=>{(!f.id.trim()||!f.modelPath.trim())&&d(n,`${i}.concreteBindings[${I}]`,"incomplete_concrete_binding","Concrete bindings need an id and model path."),x(n,`${i}.concreteBindings[${I}].createdAt`,f.createdAt),x(n,`${i}.concreteBindings[${I}].updatedAt`,f.updatedAt)})),e.recordType==="freshness_signal"&&e.state==="resolved"&&(!e.resolvedAt||!e.resolvedByEventId)&&d(n,i,"incomplete_freshness_resolution","Resolved freshness signals need a time and resolving event."),e.recordType==="model_projection"&&(x(n,`${i}.appliedAt`,e.appliedAt),D(n,`${i}.authority`,e.authority,!0),e.entryIds.length===0&&d(n,`${i}.entryIds`,"empty_model_projection","Applied model projections need at least one model entry.")),e.recordType==="eval_spec"&&((!e.legacyId.trim()||!e.title.trim()||!e.prompt.trim())&&d(n,i,"incomplete_eval_spec","Eval specs need a stable id, title, and prompt."),(e.assertions.length===0||e.assertions.some(f=>!f.trim()))&&d(n,`${i}.assertions`,"empty_eval_assertions","Eval specs need at least one non-empty assertion."),e.targets.length===0&&e.decisionIds.length===0&&re(n,i,"unbound_eval_spec","Eval spec is not yet bound to canonical product truth."),(e.dependencies?.length??0)===0&&re(n,`${i}.dependencies`,"unscoped_eval_spec","Eval spec has no freshness dependencies."))}function Ce(n,e,i){if($(n,`${i}.id`,e.id),$(n,`${i}.projectId`,e.projectId),$(n,`${i}.participantId`,e.participantId),$(n,`${i}.from.entityId`,e.from.entityId),$(n,`${i}.to.entityId`,e.to.entityId),x(n,`${i}.createdAt`,e.createdAt),e.reason.trim()||d(n,`${i}.reason`,"missing_relationship_reason","Relationships need a reason."),new Set(["supports","contradicts","supersedes","excepts"]).has(e.relationshipType)){let f=e.from.entityType==="decision"&&e.to.entityType==="decision",I=e.from.entityType==="advisory_explanation"&&e.to.entityType==="advisory_explanation";!f&&!I&&d(n,i,"invalid_normative_relationship","These relationships connect decisions to decisions or advisory explanations to advisory explanations."),f&&!e.authority?d(n,`${i}.authority`,"missing_relationship_authority","Normative relationships require explicit authority context."):f&&e.authority&&D(n,`${i}.authority`,e.authority,!0)}["operationalizes","refines","instantiates"].includes(e.relationshipType)&&(e.from.entityType!=="advisory_explanation"||e.to.entityType!=="advisory_explanation")&&d(n,i,"invalid_advisory_relationship","Advisory topology relationships connect advisory explanations."),e.relationshipType==="implements"&&(e.from.entityType!=="implementation_attempt"||e.to.entityType!=="decision")&&d(n,i,"invalid_implements_relationship","`implements` points from an implementation attempt to a decision."),e.relationshipType==="verifies"&&(e.from.entityType!=="verification_attempt"||!["decision","implementation_attempt","model_entry"].includes(e.to.entityType))&&d(n,i,"invalid_verifies_relationship","`verifies` points from a verification attempt to a verifiable target."),e.relationshipType==="replaces"&&e.from.entityType!==e.to.entityType&&d(n,i,"invalid_replaces_relationship","`replaces` connects records of the same entity type.")}function ye(n){let e=[];$(e,"manifest.projectId",n.manifest.projectId),x(e,"manifest.createdAt",n.manifest.createdAt),x(e,"manifest.updatedAt",n.manifest.updatedAt);let i=new Map,m=(t,a)=>{let s=i.get(t);s?d(e,a,"duplicate_id",`ID is already used at ${s}.`):i.set(t,a)};n.records.forEach((t,a)=>{let s=`records[${a}]`;m(t.id,s),ke(e,t,s,n.manifest.projectId)}),n.events.forEach((t,a)=>{let s=`events[${a}]`;m(t.id,s),xe(e,t,s),t.projectId!==n.manifest.projectId&&d(e,`${s}.projectId`,"project_mismatch","Event belongs to another project.")}),n.relationships.forEach((t,a)=>{let s=`relationships[${a}]`;m(t.id,s),Ce(e,t,s),t.projectId!==n.manifest.projectId&&d(e,`${s}.projectId`,"project_mismatch","Relationship belongs to another project.")}),n.artifacts.forEach((t,a)=>{m(t.id,`artifacts[${a}]`),$(e,`artifacts[${a}].id`,t.id)}),n.tombstones.forEach((t,a)=>{let s=`tombstones[${a}]`;m(t.id,s),$(e,`${s}.id`,t.id),$(e,`${s}.objectId`,t.objectId),$(e,`${s}.deletedById`,t.deletedById),x(e,`${s}.deletedAt`,t.deletedAt),D(e,`${s}.authority`,t.authority,!0)});let f=new Set(n.records.map(t=>`${t.recordType}:${t.id}`)),I=new Set(n.tombstones.map(t=>`${t.objectType}:${t.objectId}`)),y=(t,a)=>{let s=`${t.entityType}:${t.entityId}`;!f.has(s)&&!I.has(s)&&d(e,a,"dangling_entity_reference",`No record or tombstone exists for ${s}.`)};n.events.forEach((t,a)=>y(t.entity,`events[${a}].entity`)),n.relationships.forEach((t,a)=>{y(t.from,`relationships[${a}].from`),y(t.to,`relationships[${a}].to`)});let z=new Set(n.artifacts.map(t=>t.id)),S=(t,a)=>{z.has(t)||d(e,a,"dangling_artifact_reference","No artifact manifest entry exists.")},u=(t,a,s)=>{!f.has(`${t}:${a}`)&&!I.has(`${t}:${a}`)&&d(e,s,"dangling_entity_reference",`No ${t} record or tombstone exists.`)};n.records.forEach((t,a)=>{let s=`records[${a}]`;switch(t.recordType){case"authority_grant":u("participant",t.granteeId,`${s}.granteeId`),u("participant",t.grantedById,`${s}.grantedById`),t.subjectIds.forEach((o,r)=>u("subject",o,`${s}.subjectIds[${r}]`));break;case"observation":t.captureContext.subjectIds.forEach((o,r)=>u("subject",o,`${s}.captureContext.subjectIds[${r}]`)),t.captureContext.artifactIds.forEach((o,r)=>S(o,`${s}.captureContext.artifactIds[${r}]`));break;case"proposal":case"decision":t.subjects.forEach((o,r)=>u("subject",o.subjectId,`${s}.subjects[${r}].subjectId`));break;case"thread":t.messageArtifactIds.forEach((o,r)=>S(o,`${s}.messageArtifactIds[${r}]`)),t.resultRefs.forEach((o,r)=>y(o,`${s}.resultRefs[${r}]`));break;case"iteration":t.threadIds.forEach((o,r)=>u("thread",o,`${s}.threadIds[${r}]`)),t.artifactIds.forEach((o,r)=>S(o,`${s}.artifactIds[${r}]`));break;case"evidence":t.artifactIds.forEach((o,r)=>S(o,`${s}.artifactIds[${r}]`));break;case"advisory_explanation":t.subjectIds.forEach((o,r)=>u("subject",o,`${s}.subjectIds[${r}]`)),t.evidenceIds.forEach((o,r)=>u("evidence",o,`${s}.evidenceIds[${r}]`)),t.supersededById&&u("advisory_explanation",t.supersededById,`${s}.supersededById`);break;case"implementation_attempt":t.iterationIds.forEach((o,r)=>u("iteration",o,`${s}.iterationIds[${r}]`)),t.coverageClaims.forEach((o,r)=>u("decision",o.decisionId,`${s}.coverageClaims[${r}].decisionId`)),t.artifactIds.forEach((o,r)=>S(o,`${s}.artifactIds[${r}]`));break;case"eval_spec":t.replacesSpecId&&u("eval_spec",t.replacesSpecId,`${s}.replacesSpecId`),t.decisionIds.forEach((o,r)=>u("decision",o,`${s}.decisionIds[${r}]`)),t.subjectIds.forEach((o,r)=>u("subject",o,`${s}.subjectIds[${r}]`)),(t.dependencies??[]).forEach((o,r)=>{o.kind==="subject"&&o.subjectId&&u("subject",o.subjectId,`${s}.dependencies[${r}].subjectId`)}),(t.scenarios??[]).forEach((o,r)=>{o.subjectIds?.forEach((g,k)=>u("subject",g,`${s}.scenarios[${r}].subjectIds[${k}]`))}),t.targets.forEach((o,r)=>u(o.entityType,o.entityId,`${s}.targets[${r}]`));break;case"verification_attempt":t.evalSpecId&&u("eval_spec",t.evalSpecId,`${s}.evalSpecId`),t.targets.forEach((o,r)=>u(o.entityType,o.entityId,`${s}.targets[${r}]`)),t.evidenceIds.forEach((o,r)=>u("evidence",o,`${s}.evidenceIds[${r}]`));break;case"model_entry":t.subjectIds.forEach((o,r)=>u("subject",o,`${s}.subjectIds[${r}]`)),t.decisionIds.forEach((o,r)=>u("decision",o,`${s}.decisionIds[${r}]`));break;case"model_projection":D(e,`${s}.authority`,t.authority,!0),u("participant",t.appliedById,`${s}.appliedById`),t.decisionIds.forEach((o,r)=>u("decision",o,`${s}.decisionIds[${r}]`)),t.entryIds.forEach((o,r)=>u("model_entry",o,`${s}.entryIds[${r}]`)),t.coverage.forEach((o,r)=>u("decision",o.decisionId,`${s}.coverage[${r}].decisionId`));break;case"freshness_signal":y(t.target,`${s}.target`),t.evidenceIds.forEach((o,r)=>u("evidence",o,`${s}.evidenceIds[${r}]`));break;default:break}});let ne=new Map(n.events.map(t=>[t.id,t])),L=new Map(n.records.map(t=>[`${t.recordType}:${t.id}`,t])),q=new Map;n.events.forEach((t,a)=>{let s=`${t.entity.entityType}:${t.entity.entityId}:${t.fromState??"null"}`,o=q.get(s)??new Set;o.add(t.toState),q.set(s,o),o.size>1&&d(e,`events[${a}]`,"concurrent_incompatible_transitions","The same entity state has multiple incompatible successor states.")});let j=new Map(n.records.flatMap(t=>t.recordType==="authority_grant"?[[t.id,t]]:[])),v=(t,a,s,o,r)=>{if(t.level!=="delegate"||!t.grantId)return;let g=j.get(t.grantId);if(!g){d(e,r,"invalid_authority_grant","Delegated authority references a missing grant.");return}(g.granteeId!==a||g.level!=="delegate")&&d(e,r,"authority_grantee_mismatch","The grant does not authorize this participant as a delegate.");let k=Date.parse(s);(k<Date.parse(g.startsAt)||g.endsAt&&k>Date.parse(g.endsAt)||g.revokedAt&&k>=Date.parse(g.revokedAt))&&d(e,r,"inactive_authority_grant","The delegated authority grant was not active at this time."),g.subjectIds.length&&o.length&&!o.every(Q=>g.subjectIds.includes(Q))&&d(e,r,"authority_scope_mismatch","The delegated action exceeds the grant subject scope.")};for(let t of n.records)t.recordType==="decision"&&v(t.authority,t.acceptedById,t.createdAt,t.subjects.map(a=>a.subjectId),`records:${t.id}.authority`);n.events.forEach((t,a)=>{let s=L.get(`${t.entity.entityType}:${t.entity.entityId}`),o=s&&"subjects"in s?s.subjects.map(r=>r.subjectId):[];v(t.authority,t.participantId,t.createdAt,o,`events[${a}].authority`)}),n.relationships.forEach((t,a)=>{if(!t.authority)return;let s=[t.from,t.to].flatMap(o=>{let r=L.get(`${o.entityType}:${o.entityId}`);return r&&"subjects"in r?r.subjects.map(g=>g.subjectId):[]});v(t.authority,t.participantId,t.createdAt,s,`relationships[${a}].authority`)});for(let t of n.records){if(t.recordType!=="decision")continue;let a=ne.get(t.acceptanceEventId);(!a||a.entity.entityType!=="proposal"||a.entity.entityId!==t.proposalId||a.toState!=="accepted")&&d(e,`records:${t.id}.acceptanceEventId`,"invalid_acceptance_event","A decision must reference the proposal event that explicitly accepted it."),a&&a.participantId!==t.acceptedById&&d(e,`records:${t.id}.acceptedById`,"acceptor_mismatch","Decision acceptor must match the acceptance event participant."),L.has(`proposal:${t.proposalId}`)||d(e,`records:${t.id}.proposalId`,"missing_proposal","Accepted decisions must retain their proposal."),t.state==="superseded"&&(n.relationships.some(o=>o.relationshipType==="supersedes"&&o.to.entityType==="decision"&&o.to.entityId===t.id)||d(e,`records:${t.id}.state`,"missing_successor","Superseded decisions require an explicit successor relationship.")),t.state==="revoked"&&(n.events.some(o=>o.entity.entityType==="decision"&&o.entity.entityId===t.id&&o.toState==="revoked"&&!!o.reason?.trim())||d(e,`records:${t.id}.state`,"missing_revocation_event","Revoked decisions require an authorized event with a reason."))}for(let t of n.records){if(t.recordType!=="proposal"||t.state!=="accepted")continue;n.records.some(s=>s.recordType==="decision"&&s.proposalId===t.id)||d(e,`records:${t.id}.state`,"accepted_proposal_without_decision","Every accepted proposal must produce an immutable decision.")}return Re(e)}var qe=["f5258a13","31ffc15e","3eae3a70","c185e614","33930045","55e04c59","f3bb881b","f8a55928","eac95a7d","e402bdc2","2854624b","cf28ad45","6a494fab","987e901b","ad7293aa","dd1d5d77","14c429d6","48494ad3","d6bbe932","e8b94260","f56fa283","7f1f6cb3","f239f4ac","bd671e61","dbe032ec","c0808b95"];function K(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)?n:null}function A(n,e=0){return new Date(Number.isFinite(n)?n:e).toISOString()}function he(...n){return n.find(e=>!!e?.trim())?.trim()}function _(n,e,i,m){let I=Math.max(0,Math.min(Math.floor(m),0xffffffffffff)).toString(16).padStart(12,"0"),y=Me("sha256").update(`${n}\0${e}\0${i}`).digest("hex"),z=(Number.parseInt(y[3],16)&3|8).toString(16);return`${I.slice(0,8)}-${I.slice(8)}-7${y.slice(0,3)}-${z}${y.slice(4,7)}-${y.slice(7,19)}`}async function ae(n,e){try{return JSON.parse(await Le(n,"utf8"))}catch(i){return e.push({severity:"warning",code:"source_unavailable",source:n,message:i instanceof Error?i.message:String(i)}),null}}function Oe(n){let e=K(n);if(!e)return 0;let i=0,m=f=>{let I=K(f);if(!I){i+=1;return}for(let y of Object.values(I))m(y)};for(let f of Object.values(e))m(f);return i}function Ne(n){let e={};for(let i of n)e[i.recordType]=(e[i.recordType]??0)+1;return e}async function Ve(n){let e=[],i=await Be(n.projectRoot).catch(()=>n.projectRoot),m=X(i,".popmelt"),f=await ae(X(m,"threads.json"),e),I=await ae(X(m,"model.json"),e),y=K(f),z=K(y?.threads)??{},S=Object.entries(z).map(([c,p])=>({key:c,value:K(p)})).filter(c=>!!c.value),u=X(m,"decisions"),ne=await Pe(u).catch(()=>[]),L=[];for(let c of ne.filter(p=>p.endsWith(".json")).sort()){let p=K(await ae(X(u,c),e));p&&L.push({file:c,value:p})}let q=S.flatMap(({value:c})=>[c.createdAt,c.updatedAt]).filter(c=>typeof c=="number"&&Number.isFinite(c)),j=q.length?Math.min(...q):0,v=n.projectKey??i;n.projectKey||e.push({severity:"info",code:"path_derived_project_identity",message:"Canonical project identity is stable for this path; pass projectKey to preserve it across moves."});let t=_(v,"project",v,j),a=_(v,"participant","legacy-owner",j),s=_(v,"participant","legacy-agent",j),o=_(v,"subject","project",j),r=A(Math.max(j,...q)),g=[],k=[],Q=new Map,W=new Map,ce=new Map(L.map(c=>[c.value.id??c.file.replace(/^d-|\.json$/g,""),c.value])),ie=new Map,Y=(c,p,l,b,R)=>{let C=Q.get(l);if(C)return C;let P=_(v,"artifact",c,b);return k.push({id:P,kind:p,mediaType:R,location:l,availability:"available"}),Q.set(l,P),P};for(let{file:c,value:p}of L){let l=p.id??c.replace(/^d-|\.json$/g,""),b=p.createdAt??j,R=[Y(`${l}:envelope`,"other",`.popmelt/decisions/${c}`,b,"application/json")];p.screenshotPath&&R.push(Y(`${l}:screenshot`,"screenshot",`.popmelt/${p.screenshotPath.replace(/^\.popmelt\//,"")}`,b,p.screenshotPath.endsWith(".png")?"image/png":"image/webp"));for(let[C,P]of(p.pastedImagePaths??[]).entries())R.push(Y(`${l}:image:${C}`,"image",P,b));ie.set(l,R)}let M=(c,p,l)=>({id:c,schemaVersion:1,projectId:t,createdAt:r,participantId:p,sourceRefs:l}),Z=(c,p)=>{g.push(p);let l=W.get(c)??[];l.push(p.id),W.set(c,l)},ve=[{...M(a,a,[]),recordType:"participant",kind:"human",displayName:"Legacy project owner",status:"active"},{...M(s,s,[]),recordType:"participant",kind:"ai",displayName:"Legacy coding agent",status:"active"}];g.push(...ve),g.push({...M(o,a,[]),recordType:"subject",subjectType:"project",label:De(process.cwd(),i)||i,aliases:[],locators:[{id:_(v,"locator",i,j),kind:"project_root",value:i,status:"current",validFrom:A(j),sourceRefs:[]}]});let de=new Map,pe=(c,p)=>{let l=de.get(c);if(l)return l;let b=_(v,"subject",c,p),R={...M(b,a,[{kind:"external",id:c}]),createdAt:A(p),recordType:"subject",subjectType:"element",label:c,aliases:[],locators:[{id:_(v,"locator",c,p),kind:"dom_selector",value:c,status:"current",validFrom:A(p),sourceRefs:[{kind:"external",id:c}]}]};return g.push(R),de.set(c,b),b};for(let{key:c,value:p}of S){let l=p.id??c,b=p.createdAt??j,R=_(v,"thread",l,b),C={kind:"thread",id:l},P=[],H=[],ue=Array.isArray(p.messages)?p.messages:[],O,se,me=0;ue.forEach((h,N)=>{let T=h.timestamp??b,B=_(v,"artifact",`${l}:message:${N}`,T);if(P.push(B),k.push({id:B,kind:"message",mediaType:"application/json",location:`.popmelt/threads.json#/threads/${l}/messages/${N}`,availability:"available"}),Q.set(`.popmelt/threads.json#/threads/${l}/messages/${N}`,B),h.screenshotPath&&Y(`${l}:message:${N}:screenshot`,"screenshot",h.screenshotPath,T),h.role==="human"){O=h;let E=h.feedbackSummary??h.replyToQuestion;if(E?.trim()){let w=_(v,"observation",`${l}:${N}`,T),U=p.elementIdentifiers??[],te={...M(w,a,[C,{kind:"message",id:B}]),createdAt:A(T),recordType:"observation",state:"open",statement:E,captureContext:{subjectIds:U.map(G=>pe(G,b)),artifactIds:[B]},resolvedByIds:[]};Z(l,te),se=w,H.push({entityType:"observation",entityId:w})}return}if(h.role!=="assistant")return;let V=h.jobId??`${l}:${N}`,F=_(v,"iteration",V,T),J=ce.get(V),_e=h.cancelled?"cancelled":h.error?"failed":h.question?"question_asked":(h.resolutions?.length??0)>0?"completed":"no_change",je={...M(F,s,[C,{kind:"message",id:B},...(ie.get(V)??[]).map(E=>({kind:"artifact",id:E}))]),createdAt:A(T),recordType:"iteration",threadIds:[R],startedAt:A(O?.timestamp,T),completedAt:A(T),requestSummary:he(O?.feedbackSummary,O?.replyToQuestion)??"[legacy request unavailable]",responseSummary:h.question??h.error??h.responseText?.slice(0,1e3),outcome:_e,execution:{provider:h.provider??J?.provider,model:h.model??J?.model,sessionId:h.sessionId??J?.sessionId},artifactIds:[B,...ie.get(V)??[]]};Z(l,je),H.push({entityType:"iteration",entityId:F});let oe=h.resolutions??J?.resolutions??[];for(let[E,w]of oe.entries()){if(w.status!=="resolved"||!w.summary?.trim())continue;let U=p.elementIdentifiers??[],te=(U.length?U:[i]).map(ge=>({subjectId:ge===i?o:pe(ge,b),role:"governed"})),G=_(v,"proposal",`${V}:${w.annotationId??"resolution"}:${E}`,T),Te={...M(G,s,[C,{kind:"iteration",id:F}]),createdAt:A(T),recordType:"proposal",state:"pending",claim:w.summary,subjects:te,subjectSemantics:te.length>1?"Legacy thread grouped these selected elements; independent scope requires owner review.":void 0,origin:{mode:"inferred",sourceText:he(O?.feedbackSummary,O?.replyToQuestion,w.summary),iterationId:F,inferredById:s}};Z(l,Te),H.push({entityType:"proposal",entityId:G}),e.push({severity:"warning",code:"acceptance_unresolved",source:l,message:`Proposal ${G} remains pending; legacy resolved status proves an outcome, not explicit acceptance.`})}if(oe.some(E=>E.status==="resolved")||J?.gitDiff){let E=_(v,"implementation",V,T),w={...M(E,s,[C,{kind:"iteration",id:F}]),createdAt:A(T),recordType:"implementation_attempt",state:"completed",iterationIds:[F],coverageClaims:[],summary:oe.map(U=>U.summary).filter(Boolean).join(" ")||"Legacy implementation outcome.",artifactIds:[]};Z(l,w),H.push({entityType:"implementation_attempt",entityId:E}),me+=1}se&&(se=void 0)});let fe=ue.at(-1),be={...M(R,a,[C]),createdAt:A(b),recordType:"thread",state:fe?.question?"open":"resolved",messageArtifactIds:P,outcome:fe?.question?"question_unresolved":me?"implementation_only":"no_outcome",resultRefs:H};g.push(be),W.set(l,[R,...W.get(l)??[]])}let ee=Oe(I);ee&&e.push({severity:"warning",code:"model_entries_deferred",source:".popmelt/model.json",message:`${ee} model values were not promoted because their accepted decision provenance is unresolved.`});let le={manifest:{formatVersion:1,projectId:t,createdAt:A(j),updatedAt:r,features:["authority","subjects","implementations","eval_specs","portable_artifacts","bounded_retrieval"],writer:{name:"@popmelt.com/core legacy importer",version:n.writerVersion??"0.8.4-dev"}},records:g,events:[],relationships:[],artifacts:k,tombstones:[]},Ie=ye(le),$e=(n.proofCaseIds??qe).map(c=>({legacyId:c,threadFound:S.some(({key:p,value:l})=>(l.id??p)===c),decisionEnvelopeFound:ce.has(c),recordIds:W.get(c)??[]}));return{bundle:le,report:{projectRoot:i,source:{threads:S.length,messages:S.reduce((c,p)=>c+(p.value.messages?.length??0),0),decisionEnvelopes:L.length,modelEntries:ee,artifactsReferenced:k.length},imported:Ne(g),unresolvedAcceptance:e.filter(c=>c.code==="acceptance_unresolved").length,deferredModelEntries:ee,proofCases:$e,issues:e,schemaIssues:Ie.issues}}}export{Ve as importLegacyProject,_ as legacyUuidV7};
1
+ import{createHash as Me}from"crypto";import{readFile as Le,readdir as Pe,realpath as Be}from"fs/promises";import{join as X,relative as De}from"path";var Ae=/^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;function Se(n){return Ae.test(n)}function Re(n){return{valid:!n.some(e=>e.severity==="error"),issues:n}}function d(n,e,i,m){n.push({path:e,code:i,message:m,severity:"error"})}function re(n,e,i,m){n.push({path:e,code:i,message:m,severity:"warning"})}function $(n,e,i){Se(i)||d(n,e,"invalid_uuid_v7","Canonical IDs must be UUIDv7 values.")}function x(n,e,i){(!i||Number.isNaN(Date.parse(i)))&&d(n,e,"invalid_timestamp","Timestamps must be parseable ISO-8601 strings.")}function D(n,e,i,m=!1){m&&i.level==="contributor"&&d(n,`${e}.level`,"insufficient_authority","Contributors cannot accept or change normative product truth."),i.level==="delegate"&&!i.grantId&&d(n,`${e}.grantId`,"missing_authority_grant","Delegate authority must reference the grant used for this action.")}var Ee={observation:new Set(["null->open","open->resolved","open->dismissed","resolved->open","dismissed->open"]),proposal:new Set(["null->draft","draft->pending","pending->accepted","pending->rejected","pending->withdrawn","pending->deferred","deferred->pending"]),decision:new Set(["null->active","active->superseded","active->revoked"]),advisory_explanation:new Set(["null->emerging","null->testing","null->grounded","null->challenged","null->retired","emerging->testing","emerging->grounded","emerging->challenged","emerging->retired","testing->grounded","testing->challenged","testing->retired","grounded->challenged","grounded->retired","challenged->testing","challenged->retired"]),implementation_attempt:new Set(["null->planned","planned->in_progress","planned->abandoned","in_progress->completed","in_progress->failed","in_progress->abandoned"]),eval_spec:new Set(["null->draft","null->active","draft->active","draft->retired","active->retired"]),verification_attempt:new Set(["null->queued","queued->running","queued->cancelled","running->passed","running->failed","running->inconclusive","running->error","running->cancelled"]),freshness_signal:new Set(["null->open","open->resolved"])},we=new Set(["proposal:accepted","proposal:rejected","decision:superseded","decision:revoked"]);function xe(n,e,i){$(n,`${i}.id`,e.id),$(n,`${i}.projectId`,e.projectId),$(n,`${i}.participantId`,e.participantId),$(n,`${i}.entity.entityId`,e.entity.entityId),x(n,`${i}.createdAt`,e.createdAt),D(n,`${i}.authority`,e.authority);let m=Ee[e.entity.entityType],f=`${e.fromState??"null"}->${e.toState}`;m&&!m.has(f)&&d(n,i,"invalid_lifecycle_transition",`${e.entity.entityType} does not allow ${f}.`);let I=`${e.entity.entityType}:${e.toState}`;if(we.has(I)&&(D(n,`${i}.authority`,e.authority,!0),e.reason?.trim()||d(n,`${i}.reason`,"missing_normative_reason","Normative acceptance, rejection, supersession, and revocation require a reason.")),e.entity.entityType==="proposal"&&e.toState==="deferred"){let y=e.transitionContext;(y?.kind!=="proposal_deferral"||y.resurfaceWhen.length===0)&&d(n,`${i}.transitionContext`,"missing_deferral_policy","Deferred proposals require structured resurfacing conditions."),y?.resurfaceWhen.includes("after_date")&&!y.revisitAfter&&d(n,`${i}.transitionContext.revisitAfter`,"missing_revisit_date","after_date resurfacing requires revisitAfter."),y?.revisitAfter&&x(n,`${i}.transitionContext.revisitAfter`,y.revisitAfter)}}function ke(n,e,i,m){$(n,`${i}.id`,e.id),$(n,`${i}.projectId`,e.projectId),$(n,`${i}.participantId`,e.participantId),x(n,`${i}.createdAt`,e.createdAt),e.projectId!==m&&d(n,`${i}.projectId`,"project_mismatch","Record belongs to another project."),"subjects"in e&&e.subjects.length===0&&d(n,`${i}.subjects`,"missing_subject","Proposals and decisions need a subject."),"subjects"in e&&e.subjects.length>1&&!e.subjectSemantics?.trim()&&d(n,`${i}.subjectSemantics`,"missing_subject_semantics","Multi-subject claims must explain why the subjects are inseparable."),e.recordType==="proposal"&&e.origin.mode==="inferred"&&(!e.origin.sourceText||!e.origin.iterationId||!e.origin.inferredById)&&d(n,`${i}.origin`,"incomplete_inference_provenance","Inferred structure requires source text, iteration, and inferring participant."),e.recordType==="decision"&&(D(n,`${i}.authority`,e.authority,!0),e.claim.trim()||d(n,`${i}.claim`,"empty_claim","Accepted decisions require a claim.")),e.recordType==="authority_grant"&&e.level==="owner"&&re(n,`${i}.level`,"owner_grant_requires_policy_review","Owner grants are valid but should receive explicit policy review."),e.recordType==="advisory_explanation"&&((!e.statement.trim()||!e.rationale.trim())&&d(n,i,"incomplete_advisory_explanation","Advisory explanations need a statement and rationale."),x(n,`${i}.updatedAt`,e.updatedAt),e.subjectIds.length===0&&d(n,`${i}.subjectIds`,"missing_subject","Advisory explanations need a subject."),e.scope.values.some(f=>!f.trim())&&d(n,`${i}.scope.values`,"empty_scope_value","Advisory scope values cannot be empty."),e.concreteBindings.forEach((f,I)=>{(!f.id.trim()||!f.modelPath.trim())&&d(n,`${i}.concreteBindings[${I}]`,"incomplete_concrete_binding","Concrete bindings need an id and model path."),x(n,`${i}.concreteBindings[${I}].createdAt`,f.createdAt),x(n,`${i}.concreteBindings[${I}].updatedAt`,f.updatedAt)})),e.recordType==="freshness_signal"&&e.state==="resolved"&&(!e.resolvedAt||!e.resolvedByEventId)&&d(n,i,"incomplete_freshness_resolution","Resolved freshness signals need a time and resolving event."),e.recordType==="model_projection"&&(x(n,`${i}.appliedAt`,e.appliedAt),D(n,`${i}.authority`,e.authority,!0),e.entryIds.length===0&&d(n,`${i}.entryIds`,"empty_model_projection","Applied model projections need at least one model entry.")),e.recordType==="eval_spec"&&((!e.legacyId.trim()||!e.title.trim()||!e.prompt.trim())&&d(n,i,"incomplete_eval_spec","Eval specs need a stable id, title, and prompt."),(e.assertions.length===0||e.assertions.some(f=>!f.trim()))&&d(n,`${i}.assertions`,"empty_eval_assertions","Eval specs need at least one non-empty assertion."),e.targets.length===0&&e.decisionIds.length===0&&re(n,i,"unbound_eval_spec","Eval spec is not yet bound to canonical product truth."),(e.dependencies?.length??0)===0&&re(n,`${i}.dependencies`,"unscoped_eval_spec","Eval spec has no freshness dependencies."))}function Ce(n,e,i){if($(n,`${i}.id`,e.id),$(n,`${i}.projectId`,e.projectId),$(n,`${i}.participantId`,e.participantId),$(n,`${i}.from.entityId`,e.from.entityId),$(n,`${i}.to.entityId`,e.to.entityId),x(n,`${i}.createdAt`,e.createdAt),e.reason.trim()||d(n,`${i}.reason`,"missing_relationship_reason","Relationships need a reason."),new Set(["supports","contradicts","supersedes","excepts"]).has(e.relationshipType)){let f=e.from.entityType==="decision"&&e.to.entityType==="decision",I=e.from.entityType==="advisory_explanation"&&e.to.entityType==="advisory_explanation";!f&&!I&&d(n,i,"invalid_normative_relationship","These relationships connect decisions to decisions or advisory explanations to advisory explanations."),f&&!e.authority?d(n,`${i}.authority`,"missing_relationship_authority","Normative relationships require explicit authority context."):f&&e.authority&&D(n,`${i}.authority`,e.authority,!0)}["operationalizes","refines","instantiates"].includes(e.relationshipType)&&(e.from.entityType!=="advisory_explanation"||e.to.entityType!=="advisory_explanation")&&d(n,i,"invalid_advisory_relationship","Advisory topology relationships connect advisory explanations."),e.relationshipType==="implements"&&(e.from.entityType!=="implementation_attempt"||e.to.entityType!=="decision")&&d(n,i,"invalid_implements_relationship","`implements` points from an implementation attempt to a decision."),e.relationshipType==="verifies"&&(e.from.entityType!=="verification_attempt"||!["decision","implementation_attempt","model_entry"].includes(e.to.entityType))&&d(n,i,"invalid_verifies_relationship","`verifies` points from a verification attempt to a verifiable target."),e.relationshipType==="replaces"&&e.from.entityType!==e.to.entityType&&d(n,i,"invalid_replaces_relationship","`replaces` connects records of the same entity type.")}function ye(n){let e=[];$(e,"manifest.projectId",n.manifest.projectId),x(e,"manifest.createdAt",n.manifest.createdAt),x(e,"manifest.updatedAt",n.manifest.updatedAt);let i=new Map,m=(t,a)=>{let s=i.get(t);s?d(e,a,"duplicate_id",`ID is already used at ${s}.`):i.set(t,a)};n.records.forEach((t,a)=>{let s=`records[${a}]`;m(t.id,s),ke(e,t,s,n.manifest.projectId)}),n.events.forEach((t,a)=>{let s=`events[${a}]`;m(t.id,s),xe(e,t,s),t.projectId!==n.manifest.projectId&&d(e,`${s}.projectId`,"project_mismatch","Event belongs to another project.")}),n.relationships.forEach((t,a)=>{let s=`relationships[${a}]`;m(t.id,s),Ce(e,t,s),t.projectId!==n.manifest.projectId&&d(e,`${s}.projectId`,"project_mismatch","Relationship belongs to another project.")}),n.artifacts.forEach((t,a)=>{m(t.id,`artifacts[${a}]`),$(e,`artifacts[${a}].id`,t.id)}),n.tombstones.forEach((t,a)=>{let s=`tombstones[${a}]`;m(t.id,s),$(e,`${s}.id`,t.id),$(e,`${s}.objectId`,t.objectId),$(e,`${s}.deletedById`,t.deletedById),x(e,`${s}.deletedAt`,t.deletedAt),D(e,`${s}.authority`,t.authority,!0)});let f=new Set(n.records.map(t=>`${t.recordType}:${t.id}`)),I=new Set(n.tombstones.map(t=>`${t.objectType}:${t.objectId}`)),y=(t,a)=>{let s=`${t.entityType}:${t.entityId}`;!f.has(s)&&!I.has(s)&&d(e,a,"dangling_entity_reference",`No record or tombstone exists for ${s}.`)};n.events.forEach((t,a)=>y(t.entity,`events[${a}].entity`)),n.relationships.forEach((t,a)=>{y(t.from,`relationships[${a}].from`),y(t.to,`relationships[${a}].to`)});let z=new Set(n.artifacts.map(t=>t.id)),S=(t,a)=>{z.has(t)||d(e,a,"dangling_artifact_reference","No artifact manifest entry exists.")},u=(t,a,s)=>{!f.has(`${t}:${a}`)&&!I.has(`${t}:${a}`)&&d(e,s,"dangling_entity_reference",`No ${t} record or tombstone exists.`)};n.records.forEach((t,a)=>{let s=`records[${a}]`;switch(t.recordType){case"authority_grant":u("participant",t.granteeId,`${s}.granteeId`),u("participant",t.grantedById,`${s}.grantedById`),t.subjectIds.forEach((o,r)=>u("subject",o,`${s}.subjectIds[${r}]`));break;case"observation":t.captureContext.subjectIds.forEach((o,r)=>u("subject",o,`${s}.captureContext.subjectIds[${r}]`)),t.captureContext.artifactIds.forEach((o,r)=>S(o,`${s}.captureContext.artifactIds[${r}]`));break;case"proposal":case"decision":t.subjects.forEach((o,r)=>u("subject",o.subjectId,`${s}.subjects[${r}].subjectId`));break;case"thread":t.messageArtifactIds.forEach((o,r)=>S(o,`${s}.messageArtifactIds[${r}]`)),t.resultRefs.forEach((o,r)=>y(o,`${s}.resultRefs[${r}]`));break;case"iteration":t.threadIds.forEach((o,r)=>u("thread",o,`${s}.threadIds[${r}]`)),t.artifactIds.forEach((o,r)=>S(o,`${s}.artifactIds[${r}]`));break;case"evidence":t.artifactIds.forEach((o,r)=>S(o,`${s}.artifactIds[${r}]`));break;case"advisory_explanation":t.subjectIds.forEach((o,r)=>u("subject",o,`${s}.subjectIds[${r}]`)),t.evidenceIds.forEach((o,r)=>u("evidence",o,`${s}.evidenceIds[${r}]`)),t.supersededById&&u("advisory_explanation",t.supersededById,`${s}.supersededById`);break;case"implementation_attempt":t.iterationIds.forEach((o,r)=>u("iteration",o,`${s}.iterationIds[${r}]`)),t.coverageClaims.forEach((o,r)=>u("decision",o.decisionId,`${s}.coverageClaims[${r}].decisionId`)),t.artifactIds.forEach((o,r)=>S(o,`${s}.artifactIds[${r}]`));break;case"eval_spec":t.replacesSpecId&&u("eval_spec",t.replacesSpecId,`${s}.replacesSpecId`),t.decisionIds.forEach((o,r)=>u("decision",o,`${s}.decisionIds[${r}]`)),t.subjectIds.forEach((o,r)=>u("subject",o,`${s}.subjectIds[${r}]`)),(t.dependencies??[]).forEach((o,r)=>{o.kind==="subject"&&o.subjectId&&u("subject",o.subjectId,`${s}.dependencies[${r}].subjectId`)}),(t.scenarios??[]).forEach((o,r)=>{o.subjectIds?.forEach((g,k)=>u("subject",g,`${s}.scenarios[${r}].subjectIds[${k}]`))}),t.targets.forEach((o,r)=>u(o.entityType,o.entityId,`${s}.targets[${r}]`));break;case"verification_attempt":t.evalSpecId&&u("eval_spec",t.evalSpecId,`${s}.evalSpecId`),t.targets.forEach((o,r)=>u(o.entityType,o.entityId,`${s}.targets[${r}]`)),t.evidenceIds.forEach((o,r)=>u("evidence",o,`${s}.evidenceIds[${r}]`));break;case"model_entry":t.subjectIds.forEach((o,r)=>u("subject",o,`${s}.subjectIds[${r}]`)),t.decisionIds.forEach((o,r)=>u("decision",o,`${s}.decisionIds[${r}]`));break;case"model_projection":D(e,`${s}.authority`,t.authority,!0),u("participant",t.appliedById,`${s}.appliedById`),t.decisionIds.forEach((o,r)=>u("decision",o,`${s}.decisionIds[${r}]`)),t.entryIds.forEach((o,r)=>u("model_entry",o,`${s}.entryIds[${r}]`)),t.coverage.forEach((o,r)=>u("decision",o.decisionId,`${s}.coverage[${r}].decisionId`));break;case"freshness_signal":y(t.target,`${s}.target`),t.evidenceIds.forEach((o,r)=>u("evidence",o,`${s}.evidenceIds[${r}]`));break;default:break}});let ne=new Map(n.events.map(t=>[t.id,t])),L=new Map(n.records.map(t=>[`${t.recordType}:${t.id}`,t])),q=new Map;n.events.forEach((t,a)=>{let s=`${t.entity.entityType}:${t.entity.entityId}:${t.fromState??"null"}`,o=q.get(s)??new Set;o.add(t.toState),q.set(s,o),o.size>1&&d(e,`events[${a}]`,"concurrent_incompatible_transitions","The same entity state has multiple incompatible successor states.")});let j=new Map(n.records.flatMap(t=>t.recordType==="authority_grant"?[[t.id,t]]:[])),v=(t,a,s,o,r)=>{if(t.level!=="delegate"||!t.grantId)return;let g=j.get(t.grantId);if(!g){d(e,r,"invalid_authority_grant","Delegated authority references a missing grant.");return}(g.granteeId!==a||g.level!=="delegate")&&d(e,r,"authority_grantee_mismatch","The grant does not authorize this participant as a delegate.");let k=Date.parse(s);(k<Date.parse(g.startsAt)||g.endsAt&&k>Date.parse(g.endsAt)||g.revokedAt&&k>=Date.parse(g.revokedAt))&&d(e,r,"inactive_authority_grant","The delegated authority grant was not active at this time."),g.subjectIds.length&&o.length&&!o.every(Q=>g.subjectIds.includes(Q))&&d(e,r,"authority_scope_mismatch","The delegated action exceeds the grant subject scope.")};for(let t of n.records)t.recordType==="decision"&&v(t.authority,t.acceptedById,t.createdAt,t.subjects.map(a=>a.subjectId),`records:${t.id}.authority`);n.events.forEach((t,a)=>{let s=L.get(`${t.entity.entityType}:${t.entity.entityId}`),o=s&&"subjects"in s?s.subjects.map(r=>r.subjectId):[];v(t.authority,t.participantId,t.createdAt,o,`events[${a}].authority`)}),n.relationships.forEach((t,a)=>{if(!t.authority)return;let s=[t.from,t.to].flatMap(o=>{let r=L.get(`${o.entityType}:${o.entityId}`);return r&&"subjects"in r?r.subjects.map(g=>g.subjectId):[]});v(t.authority,t.participantId,t.createdAt,s,`relationships[${a}].authority`)});for(let t of n.records){if(t.recordType!=="decision")continue;let a=ne.get(t.acceptanceEventId);(!a||a.entity.entityType!=="proposal"||a.entity.entityId!==t.proposalId||a.toState!=="accepted")&&d(e,`records:${t.id}.acceptanceEventId`,"invalid_acceptance_event","A decision must reference the proposal event that explicitly accepted it."),a&&a.participantId!==t.acceptedById&&d(e,`records:${t.id}.acceptedById`,"acceptor_mismatch","Decision acceptor must match the acceptance event participant."),L.has(`proposal:${t.proposalId}`)||d(e,`records:${t.id}.proposalId`,"missing_proposal","Accepted decisions must retain their proposal."),t.state==="superseded"&&(n.relationships.some(o=>o.relationshipType==="supersedes"&&o.to.entityType==="decision"&&o.to.entityId===t.id)||d(e,`records:${t.id}.state`,"missing_successor","Superseded decisions require an explicit successor relationship.")),t.state==="revoked"&&(n.events.some(o=>o.entity.entityType==="decision"&&o.entity.entityId===t.id&&o.toState==="revoked"&&!!o.reason?.trim())||d(e,`records:${t.id}.state`,"missing_revocation_event","Revoked decisions require an authorized event with a reason."))}for(let t of n.records){if(t.recordType!=="proposal"||t.state!=="accepted")continue;n.records.some(s=>s.recordType==="decision"&&s.proposalId===t.id)||d(e,`records:${t.id}.state`,"accepted_proposal_without_decision","Every accepted proposal must produce an immutable decision.")}return Re(e)}var qe=["f5258a13","31ffc15e","3eae3a70","c185e614","33930045","55e04c59","f3bb881b","f8a55928","eac95a7d","e402bdc2","2854624b","cf28ad45","6a494fab","987e901b","ad7293aa","dd1d5d77","14c429d6","48494ad3","d6bbe932","e8b94260","f56fa283","7f1f6cb3","f239f4ac","bd671e61","dbe032ec","c0808b95"];function K(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)?n:null}function A(n,e=0){return new Date(Number.isFinite(n)?n:e).toISOString()}function he(...n){return n.find(e=>!!e?.trim())?.trim()}function _(n,e,i,m){let I=Math.max(0,Math.min(Math.floor(m),0xffffffffffff)).toString(16).padStart(12,"0"),y=Me("sha256").update(`${n}\0${e}\0${i}`).digest("hex"),z=(Number.parseInt(y[3],16)&3|8).toString(16);return`${I.slice(0,8)}-${I.slice(8)}-7${y.slice(0,3)}-${z}${y.slice(4,7)}-${y.slice(7,19)}`}async function ae(n,e){try{return JSON.parse(await Le(n,"utf8"))}catch(i){return e.push({severity:"warning",code:"source_unavailable",source:n,message:i instanceof Error?i.message:String(i)}),null}}function Oe(n){let e=K(n);if(!e)return 0;let i=0,m=f=>{let I=K(f);if(!I){i+=1;return}for(let y of Object.values(I))m(y)};for(let f of Object.values(e))m(f);return i}function Ne(n){let e={};for(let i of n)e[i.recordType]=(e[i.recordType]??0)+1;return e}async function Ve(n){let e=[],i=await Be(n.projectRoot).catch(()=>n.projectRoot),m=X(i,".popmelt"),f=await ae(X(m,"threads.json"),e),I=await ae(X(m,"model.json"),e),y=K(f),z=K(y?.threads)??{},S=Object.entries(z).map(([c,p])=>({key:c,value:K(p)})).filter(c=>!!c.value),u=X(m,"decisions"),ne=await Pe(u).catch(()=>[]),L=[];for(let c of ne.filter(p=>p.endsWith(".json")).sort()){let p=K(await ae(X(u,c),e));p&&L.push({file:c,value:p})}let q=S.flatMap(({value:c})=>[c.createdAt,c.updatedAt]).filter(c=>typeof c=="number"&&Number.isFinite(c)),j=q.length?Math.min(...q):0,v=n.projectKey??i;n.projectKey||e.push({severity:"info",code:"path_derived_project_identity",message:"Canonical project identity is stable for this path; pass projectKey to preserve it across moves."});let t=_(v,"project",v,j),a=_(v,"participant","legacy-owner",j),s=_(v,"participant","legacy-agent",j),o=_(v,"subject","project",j),r=A(Math.max(j,...q)),g=[],k=[],Q=new Map,W=new Map,ce=new Map(L.map(c=>[c.value.id??c.file.replace(/^d-|\.json$/g,""),c.value])),ie=new Map,Y=(c,p,l,b,R)=>{let C=Q.get(l);if(C)return C;let P=_(v,"artifact",c,b);return k.push({id:P,kind:p,mediaType:R,location:l,availability:"available"}),Q.set(l,P),P};for(let{file:c,value:p}of L){let l=p.id??c.replace(/^d-|\.json$/g,""),b=p.createdAt??j,R=[Y(`${l}:envelope`,"other",`.popmelt/decisions/${c}`,b,"application/json")];p.screenshotPath&&R.push(Y(`${l}:screenshot`,"screenshot",`.popmelt/${p.screenshotPath.replace(/^\.popmelt\//,"")}`,b,p.screenshotPath.endsWith(".png")?"image/png":"image/webp"));for(let[C,P]of(p.pastedImagePaths??[]).entries())R.push(Y(`${l}:image:${C}`,"image",P,b));ie.set(l,R)}let M=(c,p,l)=>({id:c,schemaVersion:1,projectId:t,createdAt:r,participantId:p,sourceRefs:l}),Z=(c,p)=>{g.push(p);let l=W.get(c)??[];l.push(p.id),W.set(c,l)},ve=[{...M(a,a,[]),recordType:"participant",kind:"human",displayName:"Legacy project owner",status:"active"},{...M(s,s,[]),recordType:"participant",kind:"ai",displayName:"Legacy coding agent",status:"active"}];g.push(...ve),g.push({...M(o,a,[]),recordType:"subject",subjectType:"project",label:De(process.cwd(),i)||i,aliases:[],locators:[{id:_(v,"locator",i,j),kind:"project_root",value:i,status:"current",validFrom:A(j),sourceRefs:[]}]});let de=new Map,pe=(c,p)=>{let l=de.get(c);if(l)return l;let b=_(v,"subject",c,p),R={...M(b,a,[{kind:"external",id:c}]),createdAt:A(p),recordType:"subject",subjectType:"element",label:c,aliases:[],locators:[{id:_(v,"locator",c,p),kind:"dom_selector",value:c,status:"current",validFrom:A(p),sourceRefs:[{kind:"external",id:c}]}]};return g.push(R),de.set(c,b),b};for(let{key:c,value:p}of S){let l=p.id??c,b=p.createdAt??j,R=_(v,"thread",l,b),C={kind:"thread",id:l},P=[],H=[],ue=Array.isArray(p.messages)?p.messages:[],O,se,me=0;ue.forEach((h,N)=>{let T=h.timestamp??b,B=_(v,"artifact",`${l}:message:${N}`,T);if(P.push(B),k.push({id:B,kind:"message",mediaType:"application/json",location:`.popmelt/threads.json#/threads/${l}/messages/${N}`,availability:"available"}),Q.set(`.popmelt/threads.json#/threads/${l}/messages/${N}`,B),h.screenshotPath&&Y(`${l}:message:${N}:screenshot`,"screenshot",h.screenshotPath,T),h.role==="human"){O=h;let E=h.feedbackSummary??h.replyToQuestion;if(E?.trim()){let w=_(v,"observation",`${l}:${N}`,T),U=p.elementIdentifiers??[],te={...M(w,a,[C,{kind:"message",id:B}]),createdAt:A(T),recordType:"observation",state:"open",statement:E,captureContext:{subjectIds:U.map(G=>pe(G,b)),artifactIds:[B]},resolvedByIds:[]};Z(l,te),se=w,H.push({entityType:"observation",entityId:w})}return}if(h.role!=="assistant")return;let V=h.jobId??`${l}:${N}`,F=_(v,"iteration",V,T),J=ce.get(V),_e=h.cancelled?"cancelled":h.error?"failed":h.question?"question_asked":(h.resolutions?.length??0)>0?"completed":"no_change",je={...M(F,s,[C,{kind:"message",id:B},...(ie.get(V)??[]).map(E=>({kind:"artifact",id:E}))]),createdAt:A(T),recordType:"iteration",threadIds:[R],startedAt:A(O?.timestamp,T),completedAt:A(T),requestSummary:he(O?.feedbackSummary,O?.replyToQuestion)??"[legacy request unavailable]",responseSummary:h.question??h.error??h.responseText?.slice(0,1e3),outcome:_e,execution:{provider:h.provider??J?.provider,model:h.model??J?.model,sessionId:h.sessionId??J?.sessionId},artifactIds:[B,...ie.get(V)??[]]};Z(l,je),H.push({entityType:"iteration",entityId:F});let oe=h.resolutions??J?.resolutions??[];for(let[E,w]of oe.entries()){if(w.status!=="resolved"||!w.summary?.trim())continue;let U=p.elementIdentifiers??[],te=(U.length?U:[i]).map(ge=>({subjectId:ge===i?o:pe(ge,b),role:"governed"})),G=_(v,"proposal",`${V}:${w.annotationId??"resolution"}:${E}`,T),Te={...M(G,s,[C,{kind:"iteration",id:F}]),createdAt:A(T),recordType:"proposal",state:"pending",claim:w.summary,subjects:te,subjectSemantics:te.length>1?"Legacy thread grouped these selected elements; independent scope requires owner review.":void 0,origin:{mode:"inferred",sourceText:he(O?.feedbackSummary,O?.replyToQuestion,w.summary),iterationId:F,inferredById:s}};Z(l,Te),H.push({entityType:"proposal",entityId:G}),e.push({severity:"warning",code:"acceptance_unresolved",source:l,message:`Proposal ${G} remains pending; legacy resolved status proves an outcome, not explicit acceptance.`})}if(oe.some(E=>E.status==="resolved")||J?.gitDiff){let E=_(v,"implementation",V,T),w={...M(E,s,[C,{kind:"iteration",id:F}]),createdAt:A(T),recordType:"implementation_attempt",state:"completed",iterationIds:[F],coverageClaims:[],summary:oe.map(U=>U.summary).filter(Boolean).join(" ")||"Legacy implementation outcome.",artifactIds:[]};Z(l,w),H.push({entityType:"implementation_attempt",entityId:E}),me+=1}se&&(se=void 0)});let fe=ue.at(-1),be={...M(R,a,[C]),createdAt:A(b),recordType:"thread",state:fe?.question?"open":"resolved",messageArtifactIds:P,outcome:fe?.question?"question_unresolved":me?"implementation_only":"no_outcome",resultRefs:H};g.push(be),W.set(l,[R,...W.get(l)??[]])}let ee=Oe(I);ee&&e.push({severity:"warning",code:"model_entries_deferred",source:".popmelt/model.json",message:`${ee} model values were not promoted because their accepted decision provenance is unresolved.`});let le={manifest:{formatVersion:1,projectId:t,createdAt:A(j),updatedAt:r,features:["authority","subjects","implementations","portable_artifacts","bounded_retrieval"],writer:{name:"@popmelt.com/core legacy importer",version:n.writerVersion??"0.8.4-dev"}},records:g,events:[],relationships:[],artifacts:k,tombstones:[]},Ie=ye(le),$e=(n.proofCaseIds??qe).map(c=>({legacyId:c,threadFound:S.some(({key:p,value:l})=>(l.id??p)===c),decisionEnvelopeFound:ce.has(c),recordIds:W.get(c)??[]}));return{bundle:le,report:{projectRoot:i,source:{threads:S.length,messages:S.reduce((c,p)=>c+(p.value.messages?.length??0),0),decisionEnvelopes:L.length,modelEntries:ee,artifactsReferenced:k.length},imported:Ne(g),unresolvedAcceptance:e.filter(c=>c.code==="acceptance_unresolved").length,deferredModelEntries:ee,proofCases:$e,issues:e,schemaIssues:Ie.issues}}}export{Ve as importLegacyProject,_ as legacyUuidV7};
@@ -216,12 +216,15 @@ type VerificationTarget = {
216
216
  entityType: 'decision' | 'implementation_attempt' | 'model_entry';
217
217
  entityId: MemoryId;
218
218
  };
219
+ /** @deprecated Retained only so existing memory journals remain readable. */
219
220
  type EvalSpecState = 'draft' | 'active' | 'retired';
221
+ /** @deprecated Retained only so existing memory journals remain readable. */
220
222
  type EvalDependency = {
221
223
  kind: 'model_path' | 'source_file' | 'route' | 'subject';
222
224
  value: string;
223
225
  subjectId?: MemoryId;
224
226
  };
227
+ /** @deprecated Retained only so existing memory journals remain readable. */
225
228
  type EvalScenario = {
226
229
  id: string;
227
230
  label?: string;
@@ -244,6 +247,7 @@ type EvalScenario = {
244
247
  value?: string;
245
248
  }>;
246
249
  };
250
+ /** @deprecated Retained only so existing memory journals remain readable. */
247
251
  type EvalSpecRecord = Provenance & {
248
252
  recordType: 'eval_spec';
249
253
  state: EvalSpecState;
@@ -283,7 +287,7 @@ type VerificationAttemptRecord = Provenance & {
283
287
  targets: VerificationTarget[];
284
288
  summary?: string;
285
289
  evidenceIds: MemoryId[];
286
- /** Compact presentation data for an eval run; raw output remains an artifact/thread detail. */
290
+ /** @deprecated Historical presentation data retained for journal compatibility. */
287
291
  evalRun?: {
288
292
  id: string;
289
293
  threadId?: string;
@@ -481,15 +485,6 @@ type RetrievalPacket = {
481
485
  value: JsonValue;
482
486
  decisionIds: MemoryId[];
483
487
  }>;
484
- evalSpecs: Array<{
485
- id: MemoryId;
486
- legacyId: string;
487
- state: EvalSpecState;
488
- title: string;
489
- assertionCount: number;
490
- decisionIds: MemoryId[];
491
- expansionRef: SourceReference;
492
- }>;
493
488
  decisions: RetrievalDecision[];
494
489
  conflicts: RetrievalConflict[];
495
490
  uncertainties: RetrievalUncertainty[];
@@ -763,7 +758,7 @@ type ImprintConcrete = {
763
758
  createdAt: string;
764
759
  updatedAt: string;
765
760
  };
766
- type ImprintRelationType = 'operationalizes' | 'refines' | 'supports' | 'contradicts' | 'excepts' | 'instantiates';
761
+ type ImprintRelationType = 'operationalizes' | 'refines' | 'supports' | 'contradicts' | 'excepts' | 'instantiates' | 'supersedes';
767
762
  type ImprintSummaryKind = 'added' | 'strengthened' | 'refined' | 'challenged' | 'exception' | 'consolidated';
768
763
  type ImprintThreadSummary = {
769
764
  transactionId: string;
@@ -846,58 +841,6 @@ type MemoryReviewReceipt = {
846
841
  headSequence?: number;
847
842
  };
848
843
 
849
- type EvalCaseStatus = 'pending' | 'approved' | 'rejected';
850
- type EvalCase = {
851
- id: string;
852
- title: string;
853
- status: EvalCaseStatus;
854
- category: 'component' | 'layout' | 'copy' | 'interaction' | 'visual' | 'workflow';
855
- prompt: string;
856
- assertions: string[];
857
- rationale: string;
858
- sourceDecisionIds: string[];
859
- sourceThreadIds: string[];
860
- dependencies?: EvalDependency[];
861
- scenarios?: EvalScenario[];
862
- };
863
- type EvalRunStatus = 'pass' | 'fail' | 'needs_review';
864
- type EvalAssertionRunResult = {
865
- assertion: string;
866
- status: EvalRunStatus;
867
- summary: string;
868
- evidence: string[];
869
- };
870
- type EvalRunScope = {
871
- type: 'current_page';
872
- url: string;
873
- viewport: {
874
- width: number;
875
- height: number;
876
- };
877
- };
878
- type EvalRun = {
879
- id: string;
880
- evalId: string;
881
- threadId?: string;
882
- status: EvalRunStatus;
883
- createdAt: number;
884
- completedAt: number;
885
- durationMs: number;
886
- scope: EvalRunScope;
887
- summary: string;
888
- assertionResults: EvalAssertionRunResult[];
889
- tooling: {
890
- chromeDevtools: 'available' | 'unavailable' | 'unknown';
891
- evidenceTypes: string[];
892
- };
893
- provider?: string;
894
- model?: string;
895
- screenshotPath?: string;
896
- codeFingerprint?: string;
897
- scopeFingerprint?: string;
898
- rawResponse?: string;
899
- };
900
-
901
844
  type ConversationalReviewIntent = {
902
845
  proposalId: string;
903
846
  action: 'accept' | 'edit_and_accept' | 'reject' | 'defer';
@@ -993,12 +936,6 @@ type MemoryContextResult = {
993
936
  actionPacket: ReturnType<typeof retrieveActionPacket>;
994
937
  reviewSelection: ReturnType<typeof selectContextualReviewPackets>;
995
938
  };
996
- type JournalEvalCase = EvalCase & {
997
- canonicalSpecId: string;
998
- verificationState: 'draft' | 'unverified' | 'passing' | 'failing' | 'needs_review' | 'stale' | 'retired';
999
- verifiedScopeFingerprint?: string;
1000
- verificationAttemptId?: string;
1001
- };
1002
939
  declare class MemoryService {
1003
940
  private readonly projectRoot;
1004
941
  private readonly store;
@@ -1014,12 +951,6 @@ declare class MemoryService {
1014
951
  writerVersion?: string;
1015
952
  }): Promise<MemoryServiceStatus>;
1016
953
  analyzeLegacy(options?: Omit<LegacyImportOptions, 'projectRoot'>): Promise<LegacyImportReport>;
1017
- /** One-time cutover import. Legacy eval files are never read during normal queries. */
1018
- migrateLegacyEvals(): Promise<{
1019
- migrated: boolean;
1020
- specs: number;
1021
- runs: number;
1022
- }>;
1023
954
  /** One-time cutover from the prototype graph into canonical advisory memory. */
1024
955
  migrateImprintSnapshot(): Promise<{
1025
956
  migrated: boolean;
@@ -1090,7 +1021,6 @@ declare class MemoryService {
1090
1021
  decisionIds: string[];
1091
1022
  }>;
1092
1023
  }>;
1093
- getEvalDependenciesForDecisions(decisionIds: string[]): Promise<EvalDependency[]>;
1094
1024
  recordDirectModelMutation(input: {
1095
1025
  key: string;
1096
1026
  value: JsonValue;
@@ -1099,24 +1029,6 @@ declare class MemoryService {
1099
1029
  decisionId: string;
1100
1030
  entryId: string;
1101
1031
  }>;
1102
- syncEvalSpecs(cases: EvalCase[]): Promise<JournalEvalCase[]>;
1103
- getJournalEvalCases(): Promise<JournalEvalCase[]>;
1104
- findJournalEvalCase(id: string): Promise<JournalEvalCase | null>;
1105
- updateJournalEvalCase(id: string, patch: Partial<Pick<EvalCase, 'status' | 'title' | 'assertions'>>): Promise<JournalEvalCase | null>;
1106
- getJournalEvalRuns(): Promise<EvalRun[]>;
1107
- recordEvalVerification(evalCase: EvalCase, run: EvalRun): Promise<void>;
1108
- syncLegacyEvalRuns(cases: EvalCase[], runs: EvalRun[]): Promise<void>;
1109
- markEvalVerificationExpired(input: {
1110
- evalSpecId: string;
1111
- verificationAttemptId: string;
1112
- previousFingerprint?: string;
1113
- currentFingerprint?: string;
1114
- }): Promise<void>;
1115
- reconcileEvalCases(cases: EvalCase[]): Promise<{
1116
- valid: EvalCase[];
1117
- discardedIds: string[];
1118
- }>;
1119
- private latestEvalSpec;
1120
1032
  findPendingProposalForLegacyDecision(legacyDecisionId: string): Promise<{
1121
1033
  proposalId: string;
1122
1034
  claim: string;