@popmelt.com/core 0.8.6 → 0.8.8
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.
- package/README.md +3 -18
- package/dist/bridge-entry.mjs +56 -116
- package/dist/{chunk-EYFN72RC.mjs → chunk-DLYPQXHS.mjs} +1 -1
- package/dist/cli.mjs +56 -116
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +74 -46
- package/dist/memory-legacy.d.mts +40 -5
- package/dist/memory-legacy.mjs +1 -1
- package/dist/memory-store.d.mts +116 -102
- package/dist/memory-store.mjs +3 -3
- package/dist/memory.d.mts +41 -15
- package/dist/memory.mjs +1 -1
- package/dist/plugin-astro.mjs +1 -1
- package/dist/plugin-vite.mjs +1 -1
- package/dist/server-UVBM5TBI.mjs +182 -0
- package/dist/server.d.mts +3 -1
- package/dist/server.mjs +57 -117
- package/package.json +1 -1
- package/dist/server-KCVEM3PH.mjs +0 -242
package/dist/memory-legacy.d.mts
CHANGED
|
@@ -164,6 +164,37 @@ type EvidenceRecord = Provenance & {
|
|
|
164
164
|
stance?: ParticipantStance;
|
|
165
165
|
artifactIds: MemoryId[];
|
|
166
166
|
};
|
|
167
|
+
/**
|
|
168
|
+
* An advisory explanation is learned, revisable shared understanding. It can
|
|
169
|
+
* guide future work, but it is deliberately distinct from accepted product
|
|
170
|
+
* truth (`decision`).
|
|
171
|
+
*/
|
|
172
|
+
type AdvisoryExplanationKind = 'intention' | 'principle' | 'pattern';
|
|
173
|
+
type AdvisoryExplanationState = 'emerging' | 'testing' | 'grounded' | 'challenged' | 'retired';
|
|
174
|
+
type AdvisoryExplanationScope = {
|
|
175
|
+
kind: 'project' | 'route' | 'component' | 'selector' | 'file';
|
|
176
|
+
values: string[];
|
|
177
|
+
};
|
|
178
|
+
type AdvisoryConcreteBinding = {
|
|
179
|
+
id: string;
|
|
180
|
+
modelPath: string;
|
|
181
|
+
value: JsonValue;
|
|
182
|
+
createdAt: Timestamp;
|
|
183
|
+
updatedAt: Timestamp;
|
|
184
|
+
};
|
|
185
|
+
type AdvisoryExplanationRecord = Provenance & {
|
|
186
|
+
recordType: 'advisory_explanation';
|
|
187
|
+
kind: AdvisoryExplanationKind;
|
|
188
|
+
state: AdvisoryExplanationState;
|
|
189
|
+
statement: string;
|
|
190
|
+
rationale: string;
|
|
191
|
+
scope: AdvisoryExplanationScope;
|
|
192
|
+
subjectIds: MemoryId[];
|
|
193
|
+
evidenceIds: MemoryId[];
|
|
194
|
+
concreteBindings: AdvisoryConcreteBinding[];
|
|
195
|
+
supersededById?: MemoryId;
|
|
196
|
+
updatedAt: Timestamp;
|
|
197
|
+
};
|
|
167
198
|
type CoverageClaim = {
|
|
168
199
|
decisionId: MemoryId;
|
|
169
200
|
coverage: 'partial' | 'full';
|
|
@@ -185,12 +216,15 @@ type VerificationTarget = {
|
|
|
185
216
|
entityType: 'decision' | 'implementation_attempt' | 'model_entry';
|
|
186
217
|
entityId: MemoryId;
|
|
187
218
|
};
|
|
219
|
+
/** @deprecated Retained only so existing memory journals remain readable. */
|
|
188
220
|
type EvalSpecState = 'draft' | 'active' | 'retired';
|
|
221
|
+
/** @deprecated Retained only so existing memory journals remain readable. */
|
|
189
222
|
type EvalDependency = {
|
|
190
223
|
kind: 'model_path' | 'source_file' | 'route' | 'subject';
|
|
191
224
|
value: string;
|
|
192
225
|
subjectId?: MemoryId;
|
|
193
226
|
};
|
|
227
|
+
/** @deprecated Retained only so existing memory journals remain readable. */
|
|
194
228
|
type EvalScenario = {
|
|
195
229
|
id: string;
|
|
196
230
|
label?: string;
|
|
@@ -213,6 +247,7 @@ type EvalScenario = {
|
|
|
213
247
|
value?: string;
|
|
214
248
|
}>;
|
|
215
249
|
};
|
|
250
|
+
/** @deprecated Retained only so existing memory journals remain readable. */
|
|
216
251
|
type EvalSpecRecord = Provenance & {
|
|
217
252
|
recordType: 'eval_spec';
|
|
218
253
|
state: EvalSpecState;
|
|
@@ -252,7 +287,7 @@ type VerificationAttemptRecord = Provenance & {
|
|
|
252
287
|
targets: VerificationTarget[];
|
|
253
288
|
summary?: string;
|
|
254
289
|
evidenceIds: MemoryId[];
|
|
255
|
-
/**
|
|
290
|
+
/** @deprecated Historical presentation data retained for journal compatibility. */
|
|
256
291
|
evalRun?: {
|
|
257
292
|
id: string;
|
|
258
293
|
threadId?: string;
|
|
@@ -305,13 +340,13 @@ type ModelProjectionRecord = Provenance & {
|
|
|
305
340
|
status: 'unprojected' | 'partially_projected' | 'projected' | 'stale';
|
|
306
341
|
}>;
|
|
307
342
|
};
|
|
308
|
-
type EntityType = 'participant' | 'authority_grant' | 'subject' | 'observation' | 'proposal' | 'decision' | 'thread' | 'iteration' | 'evidence' | 'implementation_attempt' | 'eval_spec' | 'verification_attempt' | 'model_entry' | 'model_projection' | 'freshness_signal';
|
|
343
|
+
type EntityType = 'participant' | 'authority_grant' | 'subject' | 'observation' | 'proposal' | 'decision' | 'thread' | 'iteration' | 'evidence' | 'advisory_explanation' | 'implementation_attempt' | 'eval_spec' | 'verification_attempt' | 'model_entry' | 'model_projection' | 'freshness_signal';
|
|
309
344
|
type MemoryObjectType = EntityType | 'relationship' | 'lifecycle_event' | 'artifact';
|
|
310
345
|
type EntityReference = {
|
|
311
346
|
entityType: EntityType;
|
|
312
347
|
entityId: MemoryId;
|
|
313
348
|
};
|
|
314
|
-
type RelationshipType = 'supports' | 'contradicts' | 'supersedes' | 'excepts' | 'duplicates' | 'implements' | 'verifies' | 'replaces' | 'derived_from';
|
|
349
|
+
type RelationshipType = 'supports' | 'contradicts' | 'supersedes' | 'excepts' | 'duplicates' | 'implements' | 'verifies' | 'replaces' | 'derived_from' | 'operationalizes' | 'refines' | 'instantiates';
|
|
315
350
|
type RelationshipRecord = Provenance & {
|
|
316
351
|
recordType: 'relationship';
|
|
317
352
|
relationshipType: RelationshipType;
|
|
@@ -374,8 +409,8 @@ type Tombstone = {
|
|
|
374
409
|
erasureLevel: 'content' | 'content_and_evidence' | 'full_where_permitted';
|
|
375
410
|
invalidates: EntityReference[];
|
|
376
411
|
};
|
|
377
|
-
type CanonicalRecord = ParticipantRecord | AuthorityGrantRecord | SubjectRecord | ObservationRecord | ProposalRecord | DecisionRecord | ThreadRecord | IterationRecord | EvidenceRecord | ImplementationAttemptRecord | EvalSpecRecord | VerificationAttemptRecord | ModelEntryRecord | ModelProjectionRecord | FreshnessSignalRecord;
|
|
378
|
-
type MemoryFeature = 'authority' | 'subjects' | 'decisions' | 'implementations' | 'verification' | 'eval_specs' | 'model_projection' | 'freshness' | 'portable_artifacts' | 'bounded_retrieval';
|
|
412
|
+
type CanonicalRecord = ParticipantRecord | AuthorityGrantRecord | SubjectRecord | ObservationRecord | ProposalRecord | DecisionRecord | ThreadRecord | IterationRecord | EvidenceRecord | AdvisoryExplanationRecord | ImplementationAttemptRecord | EvalSpecRecord | VerificationAttemptRecord | ModelEntryRecord | ModelProjectionRecord | FreshnessSignalRecord;
|
|
413
|
+
type MemoryFeature = 'authority' | 'subjects' | 'decisions' | 'advisory_explanations' | 'implementations' | 'verification' | 'eval_specs' | 'model_projection' | 'freshness' | 'portable_artifacts' | 'bounded_retrieval';
|
|
379
414
|
type ProjectMemoryManifest = {
|
|
380
415
|
formatVersion: MemoryFormatVersion;
|
|
381
416
|
projectId: MemoryId;
|
package/dist/memory-legacy.mjs
CHANGED
|
@@ -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 oe(n,e,i,m){n.push({path:e,code:i,message:m,severity:"warning"})}function I(n,e,i){Se(i)||d(n,e,"invalid_uuid_v7","Canonical IDs must be UUIDv7 values.")}function P(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"]),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){I(n,`${i}.id`,e.id),I(n,`${i}.projectId`,e.projectId),I(n,`${i}.participantId`,e.participantId),I(n,`${i}.entity.entityId`,e.entity.entityId),P(n,`${i}.createdAt`,e.createdAt),D(n,`${i}.authority`,e.authority);let m=Ee[e.entity.entityType],$=`${e.fromState??"null"}->${e.toState}`;m&&!m.has($)&&d(n,i,"invalid_lifecycle_transition",`${e.entity.entityType} does not allow ${$}.`);let j=`${e.entity.entityType}:${e.toState}`;if(we.has(j)&&(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 g=e.transitionContext;(g?.kind!=="proposal_deferral"||g.resurfaceWhen.length===0)&&d(n,`${i}.transitionContext`,"missing_deferral_policy","Deferred proposals require structured resurfacing conditions."),g?.resurfaceWhen.includes("after_date")&&!g.revisitAfter&&d(n,`${i}.transitionContext.revisitAfter`,"missing_revisit_date","after_date resurfacing requires revisitAfter."),g?.revisitAfter&&P(n,`${i}.transitionContext.revisitAfter`,g.revisitAfter)}}function ke(n,e,i,m){I(n,`${i}.id`,e.id),I(n,`${i}.projectId`,e.projectId),I(n,`${i}.participantId`,e.participantId),P(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"&&oe(n,`${i}.level`,"owner_grant_requires_policy_review","Owner grants are valid but should receive explicit policy review."),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"&&(P(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($=>!$.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&&oe(n,i,"unbound_eval_spec","Eval spec is not yet bound to canonical product truth."),(e.dependencies?.length??0)===0&&oe(n,`${i}.dependencies`,"unscoped_eval_spec","Eval spec has no freshness dependencies."))}function Ce(n,e,i){I(n,`${i}.id`,e.id),I(n,`${i}.projectId`,e.projectId),I(n,`${i}.participantId`,e.participantId),I(n,`${i}.from.entityId`,e.from.entityId),I(n,`${i}.to.entityId`,e.to.entityId),P(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)&&((e.from.entityType!=="decision"||e.to.entityType!=="decision")&&d(n,i,"invalid_normative_relationship","Normative relationships connect decisions to decisions."),e.authority?D(n,`${i}.authority`,e.authority,!0):d(n,`${i}.authority`,"missing_relationship_authority","Normative relationships require explicit authority context.")),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=[];I(e,"manifest.projectId",n.manifest.projectId),P(e,"manifest.createdAt",n.manifest.createdAt),P(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}]`),I(e,`artifacts[${a}].id`,t.id)}),n.tombstones.forEach((t,a)=>{let s=`tombstones[${a}]`;m(t.id,s),I(e,`${s}.id`,t.id),I(e,`${s}.objectId`,t.objectId),I(e,`${s}.deletedById`,t.deletedById),P(e,`${s}.deletedAt`,t.deletedAt),D(e,`${s}.authority`,t.authority,!0)});let $=new Set(n.records.map(t=>`${t.recordType}:${t.id}`)),j=new Set(n.tombstones.map(t=>`${t.objectType}:${t.objectId}`)),g=(t,a)=>{let s=`${t.entityType}:${t.entityId}`;!$.has(s)&&!j.has(s)&&d(e,a,"dangling_entity_reference",`No record or tombstone exists for ${s}.`)};n.events.forEach((t,a)=>g(t.entity,`events[${a}].entity`)),n.relationships.forEach((t,a)=>{g(t.from,`relationships[${a}].from`),g(t.to,`relationships[${a}].to`)});let Q=new Set(n.artifacts.map(t=>t.id)),S=(t,a)=>{Q.has(t)||d(e,a,"dangling_artifact_reference","No artifact manifest entry exists.")},u=(t,a,s)=>{!$.has(`${t}:${a}`)&&!j.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((r,o)=>u("subject",r,`${s}.subjectIds[${o}]`));break;case"observation":t.captureContext.subjectIds.forEach((r,o)=>u("subject",r,`${s}.captureContext.subjectIds[${o}]`)),t.captureContext.artifactIds.forEach((r,o)=>S(r,`${s}.captureContext.artifactIds[${o}]`));break;case"proposal":case"decision":t.subjects.forEach((r,o)=>u("subject",r.subjectId,`${s}.subjects[${o}].subjectId`));break;case"thread":t.messageArtifactIds.forEach((r,o)=>S(r,`${s}.messageArtifactIds[${o}]`)),t.resultRefs.forEach((r,o)=>g(r,`${s}.resultRefs[${o}]`));break;case"iteration":t.threadIds.forEach((r,o)=>u("thread",r,`${s}.threadIds[${o}]`)),t.artifactIds.forEach((r,o)=>S(r,`${s}.artifactIds[${o}]`));break;case"evidence":t.artifactIds.forEach((r,o)=>S(r,`${s}.artifactIds[${o}]`));break;case"implementation_attempt":t.iterationIds.forEach((r,o)=>u("iteration",r,`${s}.iterationIds[${o}]`)),t.coverageClaims.forEach((r,o)=>u("decision",r.decisionId,`${s}.coverageClaims[${o}].decisionId`)),t.artifactIds.forEach((r,o)=>S(r,`${s}.artifactIds[${o}]`));break;case"eval_spec":t.replacesSpecId&&u("eval_spec",t.replacesSpecId,`${s}.replacesSpecId`),t.decisionIds.forEach((r,o)=>u("decision",r,`${s}.decisionIds[${o}]`)),t.subjectIds.forEach((r,o)=>u("subject",r,`${s}.subjectIds[${o}]`)),(t.dependencies??[]).forEach((r,o)=>{r.kind==="subject"&&r.subjectId&&u("subject",r.subjectId,`${s}.dependencies[${o}].subjectId`)}),(t.scenarios??[]).forEach((r,o)=>{r.subjectIds?.forEach((f,x)=>u("subject",f,`${s}.scenarios[${o}].subjectIds[${x}]`))}),t.targets.forEach((r,o)=>u(r.entityType,r.entityId,`${s}.targets[${o}]`));break;case"verification_attempt":t.evalSpecId&&u("eval_spec",t.evalSpecId,`${s}.evalSpecId`),t.targets.forEach((r,o)=>u(r.entityType,r.entityId,`${s}.targets[${o}]`)),t.evidenceIds.forEach((r,o)=>u("evidence",r,`${s}.evidenceIds[${o}]`));break;case"model_entry":t.subjectIds.forEach((r,o)=>u("subject",r,`${s}.subjectIds[${o}]`)),t.decisionIds.forEach((r,o)=>u("decision",r,`${s}.decisionIds[${o}]`));break;case"model_projection":D(e,`${s}.authority`,t.authority,!0),u("participant",t.appliedById,`${s}.appliedById`),t.decisionIds.forEach((r,o)=>u("decision",r,`${s}.decisionIds[${o}]`)),t.entryIds.forEach((r,o)=>u("model_entry",r,`${s}.entryIds[${o}]`)),t.coverage.forEach((r,o)=>u("decision",r.decisionId,`${s}.coverage[${o}].decisionId`));break;case"freshness_signal":g(t.target,`${s}.target`),t.evidenceIds.forEach((r,o)=>u("evidence",r,`${s}.evidenceIds[${o}]`));break;default:break}});let ne=new Map(n.events.map(t=>[t.id,t])),M=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"}`,r=q.get(s)??new Set;r.add(t.toState),q.set(s,r),r.size>1&&d(e,`events[${a}]`,"concurrent_incompatible_transitions","The same entity state has multiple incompatible successor states.")});let _=new Map(n.records.flatMap(t=>t.recordType==="authority_grant"?[[t.id,t]]:[])),h=(t,a,s,r,o)=>{if(t.level!=="delegate"||!t.grantId)return;let f=_.get(t.grantId);if(!f){d(e,o,"invalid_authority_grant","Delegated authority references a missing grant.");return}(f.granteeId!==a||f.level!=="delegate")&&d(e,o,"authority_grantee_mismatch","The grant does not authorize this participant as a delegate.");let x=Date.parse(s);(x<Date.parse(f.startsAt)||f.endsAt&&x>Date.parse(f.endsAt)||f.revokedAt&&x>=Date.parse(f.revokedAt))&&d(e,o,"inactive_authority_grant","The delegated authority grant was not active at this time."),f.subjectIds.length&&r.length&&!r.every(W=>f.subjectIds.includes(W))&&d(e,o,"authority_scope_mismatch","The delegated action exceeds the grant subject scope.")};for(let t of n.records)t.recordType==="decision"&&h(t.authority,t.acceptedById,t.createdAt,t.subjects.map(a=>a.subjectId),`records:${t.id}.authority`);n.events.forEach((t,a)=>{let s=M.get(`${t.entity.entityType}:${t.entity.entityId}`),r=s&&"subjects"in s?s.subjects.map(o=>o.subjectId):[];h(t.authority,t.participantId,t.createdAt,r,`events[${a}].authority`)}),n.relationships.forEach((t,a)=>{if(!t.authority)return;let s=[t.from,t.to].flatMap(r=>{let o=M.get(`${r.entityType}:${r.entityId}`);return o&&"subjects"in o?o.subjects.map(f=>f.subjectId):[]});h(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."),M.has(`proposal:${t.proposalId}`)||d(e,`records:${t.id}.proposalId`,"missing_proposal","Accepted decisions must retain their proposal."),t.state==="superseded"&&(n.relationships.some(r=>r.relationshipType==="supersedes"&&r.to.entityType==="decision"&&r.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(r=>r.entity.entityType==="decision"&&r.entity.entityId===t.id&&r.toState==="revoked"&&!!r.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 b(n,e,i,m){let j=Math.max(0,Math.min(Math.floor(m),0xffffffffffff)).toString(16).padStart(12,"0"),g=Me("sha256").update(`${n}\0${e}\0${i}`).digest("hex"),Q=(Number.parseInt(g[3],16)&3|8).toString(16);return`${j.slice(0,8)}-${j.slice(8)}-7${g.slice(0,3)}-${Q}${g.slice(4,7)}-${g.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 Ne(n){let e=K(n);if(!e)return 0;let i=0,m=$=>{let j=K($);if(!j){i+=1;return}for(let g of Object.values(j))m(g)};for(let $ of Object.values(e))m($);return i}function Oe(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"),$=await ae(X(m,"threads.json"),e),j=await ae(X(m,"model.json"),e),g=K($),Q=K(g?.threads)??{},S=Object.entries(Q).map(([c,p])=>({key:c,value:K(p)})).filter(c=>!!c.value),u=X(m,"decisions"),ne=await Pe(u).catch(()=>[]),M=[];for(let c of ne.filter(p=>p.endsWith(".json")).sort()){let p=K(await ae(X(u,c),e));p&&M.push({file:c,value:p})}let q=S.flatMap(({value:c})=>[c.createdAt,c.updatedAt]).filter(c=>typeof c=="number"&&Number.isFinite(c)),_=q.length?Math.min(...q):0,h=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=b(h,"project",h,_),a=b(h,"participant","legacy-owner",_),s=b(h,"participant","legacy-agent",_),r=b(h,"subject","project",_),o=A(Math.max(_,...q)),f=[],x=[],W=new Map,z=new Map,ce=new Map(M.map(c=>[c.value.id??c.file.replace(/^d-|\.json$/g,""),c.value])),ie=new Map,Y=(c,p,l,v,R)=>{let k=W.get(l);if(k)return k;let L=b(h,"artifact",c,v);return x.push({id:L,kind:p,mediaType:R,location:l,availability:"available"}),W.set(l,L),L};for(let{file:c,value:p}of M){let l=p.id??c.replace(/^d-|\.json$/g,""),v=p.createdAt??_,R=[Y(`${l}:envelope`,"other",`.popmelt/decisions/${c}`,v,"application/json")];p.screenshotPath&&R.push(Y(`${l}:screenshot`,"screenshot",`.popmelt/${p.screenshotPath.replace(/^\.popmelt\//,"")}`,v,p.screenshotPath.endsWith(".png")?"image/png":"image/webp"));for(let[k,L]of(p.pastedImagePaths??[]).entries())R.push(Y(`${l}:image:${k}`,"image",L,v));ie.set(l,R)}let C=(c,p,l)=>({id:c,schemaVersion:1,projectId:t,createdAt:o,participantId:p,sourceRefs:l}),Z=(c,p)=>{f.push(p);let l=z.get(c)??[];l.push(p.id),z.set(c,l)},Ie=[{...C(a,a,[]),recordType:"participant",kind:"human",displayName:"Legacy project owner",status:"active"},{...C(s,s,[]),recordType:"participant",kind:"ai",displayName:"Legacy coding agent",status:"active"}];f.push(...Ie),f.push({...C(r,a,[]),recordType:"subject",subjectType:"project",label:De(process.cwd(),i)||i,aliases:[],locators:[{id:b(h,"locator",i,_),kind:"project_root",value:i,status:"current",validFrom:A(_),sourceRefs:[]}]});let de=new Map,pe=(c,p)=>{let l=de.get(c);if(l)return l;let v=b(h,"subject",c,p),R={...C(v,a,[{kind:"external",id:c}]),createdAt:A(p),recordType:"subject",subjectType:"element",label:c,aliases:[],locators:[{id:b(h,"locator",c,p),kind:"dom_selector",value:c,status:"current",validFrom:A(p),sourceRefs:[{kind:"external",id:c}]}]};return f.push(R),de.set(c,v),v};for(let{key:c,value:p}of S){let l=p.id??c,v=p.createdAt??_,R=b(h,"thread",l,v),k={kind:"thread",id:l},L=[],H=[],ue=Array.isArray(p.messages)?p.messages:[],N,se,me=0;ue.forEach((y,O)=>{let T=y.timestamp??v,B=b(h,"artifact",`${l}:message:${O}`,T);if(L.push(B),x.push({id:B,kind:"message",mediaType:"application/json",location:`.popmelt/threads.json#/threads/${l}/messages/${O}`,availability:"available"}),W.set(`.popmelt/threads.json#/threads/${l}/messages/${O}`,B),y.screenshotPath&&Y(`${l}:message:${O}:screenshot`,"screenshot",y.screenshotPath,T),y.role==="human"){N=y;let E=y.feedbackSummary??y.replyToQuestion;if(E?.trim()){let w=b(h,"observation",`${l}:${O}`,T),U=p.elementIdentifiers??[],te={...C(w,a,[k,{kind:"message",id:B}]),createdAt:A(T),recordType:"observation",state:"open",statement:E,captureContext:{subjectIds:U.map(G=>pe(G,v)),artifactIds:[B]},resolvedByIds:[]};Z(l,te),se=w,H.push({entityType:"observation",entityId:w})}return}if(y.role!=="assistant")return;let V=y.jobId??`${l}:${O}`,F=b(h,"iteration",V,T),J=ce.get(V),je=y.cancelled?"cancelled":y.error?"failed":y.question?"question_asked":(y.resolutions?.length??0)>0?"completed":"no_change",_e={...C(F,s,[k,{kind:"message",id:B},...(ie.get(V)??[]).map(E=>({kind:"artifact",id:E}))]),createdAt:A(T),recordType:"iteration",threadIds:[R],startedAt:A(N?.timestamp,T),completedAt:A(T),requestSummary:he(N?.feedbackSummary,N?.replyToQuestion)??"[legacy request unavailable]",responseSummary:y.question??y.error??y.responseText?.slice(0,1e3),outcome:je,execution:{provider:y.provider??J?.provider,model:y.model??J?.model,sessionId:y.sessionId??J?.sessionId},artifactIds:[B,...ie.get(V)??[]]};Z(l,_e),H.push({entityType:"iteration",entityId:F});let re=y.resolutions??J?.resolutions??[];for(let[E,w]of re.entries()){if(w.status!=="resolved"||!w.summary?.trim())continue;let U=p.elementIdentifiers??[],te=(U.length?U:[i]).map(ge=>({subjectId:ge===i?r:pe(ge,v),role:"governed"})),G=b(h,"proposal",`${V}:${w.annotationId??"resolution"}:${E}`,T),Te={...C(G,s,[k,{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(N?.feedbackSummary,N?.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(re.some(E=>E.status==="resolved")||J?.gitDiff){let E=b(h,"implementation",V,T),w={...C(E,s,[k,{kind:"iteration",id:F}]),createdAt:A(T),recordType:"implementation_attempt",state:"completed",iterationIds:[F],coverageClaims:[],summary:re.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),$e={...C(R,a,[k]),createdAt:A(v),recordType:"thread",state:fe?.question?"open":"resolved",messageArtifactIds:L,outcome:fe?.question?"question_unresolved":me?"implementation_only":"no_outcome",resultRefs:H};f.push($e),z.set(l,[R,...z.get(l)??[]])}let ee=Ne(j);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(_),updatedAt:o,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:f,events:[],relationships:[],artifacts:x,tombstones:[]},ve=ye(le),be=(n.proofCaseIds??qe).map(c=>({legacyId:c,threadFound:S.some(({key:p,value:l})=>(l.id??p)===c),decisionEnvelopeFound:ce.has(c),recordIds:z.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:M.length,modelEntries:ee,artifactsReferenced:x.length},imported:Oe(f),unresolvedAcceptance:e.filter(c=>c.code==="acceptance_unresolved").length,deferredModelEntries:ee,proofCases:be,issues:e,schemaIssues:ve.issues}}}export{Ve as importLegacyProject,b 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};
|
package/dist/memory-store.d.mts
CHANGED
|
@@ -164,6 +164,37 @@ type EvidenceRecord = Provenance & {
|
|
|
164
164
|
stance?: ParticipantStance;
|
|
165
165
|
artifactIds: MemoryId[];
|
|
166
166
|
};
|
|
167
|
+
/**
|
|
168
|
+
* An advisory explanation is learned, revisable shared understanding. It can
|
|
169
|
+
* guide future work, but it is deliberately distinct from accepted product
|
|
170
|
+
* truth (`decision`).
|
|
171
|
+
*/
|
|
172
|
+
type AdvisoryExplanationKind = 'intention' | 'principle' | 'pattern';
|
|
173
|
+
type AdvisoryExplanationState = 'emerging' | 'testing' | 'grounded' | 'challenged' | 'retired';
|
|
174
|
+
type AdvisoryExplanationScope = {
|
|
175
|
+
kind: 'project' | 'route' | 'component' | 'selector' | 'file';
|
|
176
|
+
values: string[];
|
|
177
|
+
};
|
|
178
|
+
type AdvisoryConcreteBinding = {
|
|
179
|
+
id: string;
|
|
180
|
+
modelPath: string;
|
|
181
|
+
value: JsonValue;
|
|
182
|
+
createdAt: Timestamp;
|
|
183
|
+
updatedAt: Timestamp;
|
|
184
|
+
};
|
|
185
|
+
type AdvisoryExplanationRecord = Provenance & {
|
|
186
|
+
recordType: 'advisory_explanation';
|
|
187
|
+
kind: AdvisoryExplanationKind;
|
|
188
|
+
state: AdvisoryExplanationState;
|
|
189
|
+
statement: string;
|
|
190
|
+
rationale: string;
|
|
191
|
+
scope: AdvisoryExplanationScope;
|
|
192
|
+
subjectIds: MemoryId[];
|
|
193
|
+
evidenceIds: MemoryId[];
|
|
194
|
+
concreteBindings: AdvisoryConcreteBinding[];
|
|
195
|
+
supersededById?: MemoryId;
|
|
196
|
+
updatedAt: Timestamp;
|
|
197
|
+
};
|
|
167
198
|
type CoverageClaim = {
|
|
168
199
|
decisionId: MemoryId;
|
|
169
200
|
coverage: 'partial' | 'full';
|
|
@@ -185,12 +216,15 @@ type VerificationTarget = {
|
|
|
185
216
|
entityType: 'decision' | 'implementation_attempt' | 'model_entry';
|
|
186
217
|
entityId: MemoryId;
|
|
187
218
|
};
|
|
219
|
+
/** @deprecated Retained only so existing memory journals remain readable. */
|
|
188
220
|
type EvalSpecState = 'draft' | 'active' | 'retired';
|
|
221
|
+
/** @deprecated Retained only so existing memory journals remain readable. */
|
|
189
222
|
type EvalDependency = {
|
|
190
223
|
kind: 'model_path' | 'source_file' | 'route' | 'subject';
|
|
191
224
|
value: string;
|
|
192
225
|
subjectId?: MemoryId;
|
|
193
226
|
};
|
|
227
|
+
/** @deprecated Retained only so existing memory journals remain readable. */
|
|
194
228
|
type EvalScenario = {
|
|
195
229
|
id: string;
|
|
196
230
|
label?: string;
|
|
@@ -213,6 +247,7 @@ type EvalScenario = {
|
|
|
213
247
|
value?: string;
|
|
214
248
|
}>;
|
|
215
249
|
};
|
|
250
|
+
/** @deprecated Retained only so existing memory journals remain readable. */
|
|
216
251
|
type EvalSpecRecord = Provenance & {
|
|
217
252
|
recordType: 'eval_spec';
|
|
218
253
|
state: EvalSpecState;
|
|
@@ -252,7 +287,7 @@ type VerificationAttemptRecord = Provenance & {
|
|
|
252
287
|
targets: VerificationTarget[];
|
|
253
288
|
summary?: string;
|
|
254
289
|
evidenceIds: MemoryId[];
|
|
255
|
-
/**
|
|
290
|
+
/** @deprecated Historical presentation data retained for journal compatibility. */
|
|
256
291
|
evalRun?: {
|
|
257
292
|
id: string;
|
|
258
293
|
threadId?: string;
|
|
@@ -305,13 +340,13 @@ type ModelProjectionRecord = Provenance & {
|
|
|
305
340
|
status: 'unprojected' | 'partially_projected' | 'projected' | 'stale';
|
|
306
341
|
}>;
|
|
307
342
|
};
|
|
308
|
-
type EntityType = 'participant' | 'authority_grant' | 'subject' | 'observation' | 'proposal' | 'decision' | 'thread' | 'iteration' | 'evidence' | 'implementation_attempt' | 'eval_spec' | 'verification_attempt' | 'model_entry' | 'model_projection' | 'freshness_signal';
|
|
343
|
+
type EntityType = 'participant' | 'authority_grant' | 'subject' | 'observation' | 'proposal' | 'decision' | 'thread' | 'iteration' | 'evidence' | 'advisory_explanation' | 'implementation_attempt' | 'eval_spec' | 'verification_attempt' | 'model_entry' | 'model_projection' | 'freshness_signal';
|
|
309
344
|
type MemoryObjectType = EntityType | 'relationship' | 'lifecycle_event' | 'artifact';
|
|
310
345
|
type EntityReference = {
|
|
311
346
|
entityType: EntityType;
|
|
312
347
|
entityId: MemoryId;
|
|
313
348
|
};
|
|
314
|
-
type RelationshipType = 'supports' | 'contradicts' | 'supersedes' | 'excepts' | 'duplicates' | 'implements' | 'verifies' | 'replaces' | 'derived_from';
|
|
349
|
+
type RelationshipType = 'supports' | 'contradicts' | 'supersedes' | 'excepts' | 'duplicates' | 'implements' | 'verifies' | 'replaces' | 'derived_from' | 'operationalizes' | 'refines' | 'instantiates';
|
|
315
350
|
type RelationshipRecord = Provenance & {
|
|
316
351
|
recordType: 'relationship';
|
|
317
352
|
relationshipType: RelationshipType;
|
|
@@ -374,8 +409,8 @@ type Tombstone = {
|
|
|
374
409
|
erasureLevel: 'content' | 'content_and_evidence' | 'full_where_permitted';
|
|
375
410
|
invalidates: EntityReference[];
|
|
376
411
|
};
|
|
377
|
-
type CanonicalRecord = ParticipantRecord | AuthorityGrantRecord | SubjectRecord | ObservationRecord | ProposalRecord | DecisionRecord | ThreadRecord | IterationRecord | EvidenceRecord | ImplementationAttemptRecord | EvalSpecRecord | VerificationAttemptRecord | ModelEntryRecord | ModelProjectionRecord | FreshnessSignalRecord;
|
|
378
|
-
type MemoryFeature = 'authority' | 'subjects' | 'decisions' | 'implementations' | 'verification' | 'eval_specs' | 'model_projection' | 'freshness' | 'portable_artifacts' | 'bounded_retrieval';
|
|
412
|
+
type CanonicalRecord = ParticipantRecord | AuthorityGrantRecord | SubjectRecord | ObservationRecord | ProposalRecord | DecisionRecord | ThreadRecord | IterationRecord | EvidenceRecord | AdvisoryExplanationRecord | ImplementationAttemptRecord | EvalSpecRecord | VerificationAttemptRecord | ModelEntryRecord | ModelProjectionRecord | FreshnessSignalRecord;
|
|
413
|
+
type MemoryFeature = 'authority' | 'subjects' | 'decisions' | 'advisory_explanations' | 'implementations' | 'verification' | 'eval_specs' | 'model_projection' | 'freshness' | 'portable_artifacts' | 'bounded_retrieval';
|
|
379
414
|
type ProjectMemoryManifest = {
|
|
380
415
|
formatVersion: MemoryFormatVersion;
|
|
381
416
|
projectId: MemoryId;
|
|
@@ -450,15 +485,6 @@ type RetrievalPacket = {
|
|
|
450
485
|
value: JsonValue;
|
|
451
486
|
decisionIds: MemoryId[];
|
|
452
487
|
}>;
|
|
453
|
-
evalSpecs: Array<{
|
|
454
|
-
id: MemoryId;
|
|
455
|
-
legacyId: string;
|
|
456
|
-
state: EvalSpecState;
|
|
457
|
-
title: string;
|
|
458
|
-
assertionCount: number;
|
|
459
|
-
decisionIds: MemoryId[];
|
|
460
|
-
expansionRef: SourceReference;
|
|
461
|
-
}>;
|
|
462
488
|
decisions: RetrievalDecision[];
|
|
463
489
|
conflicts: RetrievalConflict[];
|
|
464
490
|
uncertainties: RetrievalUncertainty[];
|
|
@@ -567,6 +593,8 @@ type OwnerReviewPlanResult = {
|
|
|
567
593
|
|
|
568
594
|
type MemoryJournalMutation = {
|
|
569
595
|
records: CanonicalRecord[];
|
|
596
|
+
/** Targeted replacement for revisable advisory records; other truth stays event-driven. */
|
|
597
|
+
recordReplacements?: CanonicalRecord[];
|
|
570
598
|
events: LifecycleEvent[];
|
|
571
599
|
relationships: RelationshipRecord[];
|
|
572
600
|
artifacts: ArtifactManifestEntry[];
|
|
@@ -716,7 +744,21 @@ type RetrievalQuery = {
|
|
|
716
744
|
};
|
|
717
745
|
declare function retrieveActionPacket(bundle: ProjectMemoryBundle, query: RetrievalQuery): RetrievalPacket;
|
|
718
746
|
|
|
747
|
+
type ImprintExplanationKind = 'intention' | 'principle' | 'pattern';
|
|
719
748
|
type ImprintExplanationState = 'emerging' | 'testing' | 'grounded' | 'challenged' | 'retired';
|
|
749
|
+
type ImprintScopeKind = 'project' | 'route' | 'component' | 'selector' | 'file';
|
|
750
|
+
type ImprintScope = {
|
|
751
|
+
kind: ImprintScopeKind;
|
|
752
|
+
values: string[];
|
|
753
|
+
};
|
|
754
|
+
type ImprintConcrete = {
|
|
755
|
+
id: string;
|
|
756
|
+
modelPath: string;
|
|
757
|
+
value: unknown;
|
|
758
|
+
createdAt: string;
|
|
759
|
+
updatedAt: string;
|
|
760
|
+
};
|
|
761
|
+
type ImprintRelationType = 'operationalizes' | 'refines' | 'supports' | 'contradicts' | 'excepts' | 'instantiates' | 'supersedes';
|
|
720
762
|
type ImprintSummaryKind = 'added' | 'strengthened' | 'refined' | 'challenged' | 'exception' | 'consolidated';
|
|
721
763
|
type ImprintThreadSummary = {
|
|
722
764
|
transactionId: string;
|
|
@@ -739,6 +781,56 @@ type ImprintThreadSummary = {
|
|
|
739
781
|
resolvedAction?: ImprintGroundingAction;
|
|
740
782
|
};
|
|
741
783
|
type ImprintGroundingAction = 'confirm' | 'reason_wrong' | 'narrow' | 'exception' | 'edit' | 'dont_learn' | 'undo';
|
|
784
|
+
type ImprintViewEvidence = {
|
|
785
|
+
id: string;
|
|
786
|
+
kind: 'judgment' | 'user_feedback' | 'project_state' | 'other';
|
|
787
|
+
summary: string;
|
|
788
|
+
createdAt: string;
|
|
789
|
+
participantKind: 'human' | 'ai' | 'system' | 'integration' | 'unknown';
|
|
790
|
+
threadId?: string;
|
|
791
|
+
jobId?: string;
|
|
792
|
+
};
|
|
793
|
+
type ImprintViewRelation = {
|
|
794
|
+
id: string;
|
|
795
|
+
type: ImprintRelationType | 'supersedes';
|
|
796
|
+
direction: 'outgoing' | 'incoming';
|
|
797
|
+
explanationId: string;
|
|
798
|
+
statement: string;
|
|
799
|
+
rationale: string;
|
|
800
|
+
};
|
|
801
|
+
type ImprintViewExplanation = {
|
|
802
|
+
id: string;
|
|
803
|
+
kind: ImprintExplanationKind;
|
|
804
|
+
state: ImprintExplanationState;
|
|
805
|
+
statement: string;
|
|
806
|
+
rationale: string;
|
|
807
|
+
scope: ImprintScope;
|
|
808
|
+
createdAt: string;
|
|
809
|
+
updatedAt: string;
|
|
810
|
+
evidenceCount: number;
|
|
811
|
+
recentEvidence: ImprintViewEvidence[];
|
|
812
|
+
concrete: ImprintConcrete[];
|
|
813
|
+
relations: ImprintViewRelation[];
|
|
814
|
+
sourceThreadIds: string[];
|
|
815
|
+
needsGrounding: boolean;
|
|
816
|
+
};
|
|
817
|
+
/** Human-shaped read model derived exclusively from canonical project memory. */
|
|
818
|
+
type ImprintView = {
|
|
819
|
+
head: {
|
|
820
|
+
sequence: number;
|
|
821
|
+
updatedAt: string;
|
|
822
|
+
};
|
|
823
|
+
counts: {
|
|
824
|
+
total: number;
|
|
825
|
+
emerging: number;
|
|
826
|
+
testing: number;
|
|
827
|
+
grounded: number;
|
|
828
|
+
challenged: number;
|
|
829
|
+
retired: number;
|
|
830
|
+
needsGrounding: number;
|
|
831
|
+
};
|
|
832
|
+
explanations: ImprintViewExplanation[];
|
|
833
|
+
};
|
|
742
834
|
|
|
743
835
|
type MemoryReviewReceipt = {
|
|
744
836
|
status: 'committed' | 'not_ready' | 'rejected';
|
|
@@ -749,58 +841,6 @@ type MemoryReviewReceipt = {
|
|
|
749
841
|
headSequence?: number;
|
|
750
842
|
};
|
|
751
843
|
|
|
752
|
-
type EvalCaseStatus = 'pending' | 'approved' | 'rejected';
|
|
753
|
-
type EvalCase = {
|
|
754
|
-
id: string;
|
|
755
|
-
title: string;
|
|
756
|
-
status: EvalCaseStatus;
|
|
757
|
-
category: 'component' | 'layout' | 'copy' | 'interaction' | 'visual' | 'workflow';
|
|
758
|
-
prompt: string;
|
|
759
|
-
assertions: string[];
|
|
760
|
-
rationale: string;
|
|
761
|
-
sourceDecisionIds: string[];
|
|
762
|
-
sourceThreadIds: string[];
|
|
763
|
-
dependencies?: EvalDependency[];
|
|
764
|
-
scenarios?: EvalScenario[];
|
|
765
|
-
};
|
|
766
|
-
type EvalRunStatus = 'pass' | 'fail' | 'needs_review';
|
|
767
|
-
type EvalAssertionRunResult = {
|
|
768
|
-
assertion: string;
|
|
769
|
-
status: EvalRunStatus;
|
|
770
|
-
summary: string;
|
|
771
|
-
evidence: string[];
|
|
772
|
-
};
|
|
773
|
-
type EvalRunScope = {
|
|
774
|
-
type: 'current_page';
|
|
775
|
-
url: string;
|
|
776
|
-
viewport: {
|
|
777
|
-
width: number;
|
|
778
|
-
height: number;
|
|
779
|
-
};
|
|
780
|
-
};
|
|
781
|
-
type EvalRun = {
|
|
782
|
-
id: string;
|
|
783
|
-
evalId: string;
|
|
784
|
-
threadId?: string;
|
|
785
|
-
status: EvalRunStatus;
|
|
786
|
-
createdAt: number;
|
|
787
|
-
completedAt: number;
|
|
788
|
-
durationMs: number;
|
|
789
|
-
scope: EvalRunScope;
|
|
790
|
-
summary: string;
|
|
791
|
-
assertionResults: EvalAssertionRunResult[];
|
|
792
|
-
tooling: {
|
|
793
|
-
chromeDevtools: 'available' | 'unavailable' | 'unknown';
|
|
794
|
-
evidenceTypes: string[];
|
|
795
|
-
};
|
|
796
|
-
provider?: string;
|
|
797
|
-
model?: string;
|
|
798
|
-
screenshotPath?: string;
|
|
799
|
-
codeFingerprint?: string;
|
|
800
|
-
scopeFingerprint?: string;
|
|
801
|
-
rawResponse?: string;
|
|
802
|
-
};
|
|
803
|
-
|
|
804
844
|
type ConversationalReviewIntent = {
|
|
805
845
|
proposalId: string;
|
|
806
846
|
action: 'accept' | 'edit_and_accept' | 'reject' | 'defer';
|
|
@@ -896,12 +936,6 @@ type MemoryContextResult = {
|
|
|
896
936
|
actionPacket: ReturnType<typeof retrieveActionPacket>;
|
|
897
937
|
reviewSelection: ReturnType<typeof selectContextualReviewPackets>;
|
|
898
938
|
};
|
|
899
|
-
type JournalEvalCase = EvalCase & {
|
|
900
|
-
canonicalSpecId: string;
|
|
901
|
-
verificationState: 'draft' | 'unverified' | 'passing' | 'failing' | 'needs_review' | 'stale' | 'retired';
|
|
902
|
-
verifiedScopeFingerprint?: string;
|
|
903
|
-
verificationAttemptId?: string;
|
|
904
|
-
};
|
|
905
939
|
declare class MemoryService {
|
|
906
940
|
private readonly projectRoot;
|
|
907
941
|
private readonly store;
|
|
@@ -917,13 +951,7 @@ declare class MemoryService {
|
|
|
917
951
|
writerVersion?: string;
|
|
918
952
|
}): Promise<MemoryServiceStatus>;
|
|
919
953
|
analyzeLegacy(options?: Omit<LegacyImportOptions, 'projectRoot'>): Promise<LegacyImportReport>;
|
|
920
|
-
/** One-time cutover
|
|
921
|
-
migrateLegacyEvals(): Promise<{
|
|
922
|
-
migrated: boolean;
|
|
923
|
-
specs: number;
|
|
924
|
-
runs: number;
|
|
925
|
-
}>;
|
|
926
|
-
/** One-time identity/evidence bridge from the prototype Imprint journal. */
|
|
954
|
+
/** One-time cutover from the prototype graph into canonical advisory memory. */
|
|
927
955
|
migrateImprintSnapshot(): Promise<{
|
|
928
956
|
migrated: boolean;
|
|
929
957
|
explanations: number;
|
|
@@ -952,10 +980,7 @@ declare class MemoryService {
|
|
|
952
980
|
proposalIds: string[];
|
|
953
981
|
headSequence?: number;
|
|
954
982
|
}>;
|
|
955
|
-
/**
|
|
956
|
-
* Mirrors Imprint identity and evidence into the canonical journal without
|
|
957
|
-
* promoting advisory explanations into product decisions.
|
|
958
|
-
*/
|
|
983
|
+
/** Continuously syncs changed Imprint explanations into canonical advisory memory. */
|
|
959
984
|
recordImprintEvidence(input: {
|
|
960
985
|
summary: ImprintThreadSummary;
|
|
961
986
|
threadId: string;
|
|
@@ -963,6 +988,13 @@ declare class MemoryService {
|
|
|
963
988
|
action?: ImprintGroundingAction;
|
|
964
989
|
occurredAt?: string;
|
|
965
990
|
}): Promise<void>;
|
|
991
|
+
/** Reconciles the durable Imprint graph into the human-facing canonical memory view. */
|
|
992
|
+
syncImprintGraph(): Promise<{
|
|
993
|
+
status: 'synced' | 'not_ready' | 'no_change';
|
|
994
|
+
relationships: number;
|
|
995
|
+
explanations: number;
|
|
996
|
+
headSequence?: number;
|
|
997
|
+
}>;
|
|
966
998
|
recover(confirmed: boolean): Promise<MemoryJournalLoadResult>;
|
|
967
999
|
diagnostics(): Promise<{
|
|
968
1000
|
status: MemoryServiceStatus;
|
|
@@ -973,6 +1005,7 @@ declare class MemoryService {
|
|
|
973
1005
|
}>;
|
|
974
1006
|
getProjectableDecisions(limit?: number): Promise<DecisionRecord[]>;
|
|
975
1007
|
getCanonicalModelEntries(): Promise<ModelEntryRecord[]>;
|
|
1008
|
+
getImprintView(pendingGroundingExplanationIds?: string[]): Promise<ImprintView>;
|
|
976
1009
|
getModelView(): Promise<{
|
|
977
1010
|
decisions: Array<{
|
|
978
1011
|
id: string;
|
|
@@ -988,7 +1021,6 @@ declare class MemoryService {
|
|
|
988
1021
|
decisionIds: string[];
|
|
989
1022
|
}>;
|
|
990
1023
|
}>;
|
|
991
|
-
getEvalDependenciesForDecisions(decisionIds: string[]): Promise<EvalDependency[]>;
|
|
992
1024
|
recordDirectModelMutation(input: {
|
|
993
1025
|
key: string;
|
|
994
1026
|
value: JsonValue;
|
|
@@ -997,24 +1029,6 @@ declare class MemoryService {
|
|
|
997
1029
|
decisionId: string;
|
|
998
1030
|
entryId: string;
|
|
999
1031
|
}>;
|
|
1000
|
-
syncEvalSpecs(cases: EvalCase[]): Promise<JournalEvalCase[]>;
|
|
1001
|
-
getJournalEvalCases(): Promise<JournalEvalCase[]>;
|
|
1002
|
-
findJournalEvalCase(id: string): Promise<JournalEvalCase | null>;
|
|
1003
|
-
updateJournalEvalCase(id: string, patch: Partial<Pick<EvalCase, 'status' | 'title' | 'assertions'>>): Promise<JournalEvalCase | null>;
|
|
1004
|
-
getJournalEvalRuns(): Promise<EvalRun[]>;
|
|
1005
|
-
recordEvalVerification(evalCase: EvalCase, run: EvalRun): Promise<void>;
|
|
1006
|
-
syncLegacyEvalRuns(cases: EvalCase[], runs: EvalRun[]): Promise<void>;
|
|
1007
|
-
markEvalVerificationExpired(input: {
|
|
1008
|
-
evalSpecId: string;
|
|
1009
|
-
verificationAttemptId: string;
|
|
1010
|
-
previousFingerprint?: string;
|
|
1011
|
-
currentFingerprint?: string;
|
|
1012
|
-
}): Promise<void>;
|
|
1013
|
-
reconcileEvalCases(cases: EvalCase[]): Promise<{
|
|
1014
|
-
valid: EvalCase[];
|
|
1015
|
-
discardedIds: string[];
|
|
1016
|
-
}>;
|
|
1017
|
-
private latestEvalSpec;
|
|
1018
1032
|
findPendingProposalForLegacyDecision(legacyDecisionId: string): Promise<{
|
|
1019
1033
|
proposalId: string;
|
|
1020
1034
|
claim: string;
|