@miadi/episodic-memory-schema 0.6.1 → 0.7.0
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/dist/observation.d.ts +125 -12
- package/dist/observation.d.ts.map +1 -1
- package/dist/observation.js +118 -10
- package/dist/observation.js.map +1 -1
- package/package.json +1 -1
package/dist/observation.d.ts
CHANGED
|
@@ -35,8 +35,17 @@ export declare function isArtifactKind(value: unknown): value is ArtifactKind;
|
|
|
35
35
|
* `captured` is unrepeatable: a device, an instant, one chance. A take that is
|
|
36
36
|
* deleted is gone, because the moment it recorded will not happen twice.
|
|
37
37
|
* `derived` is regenerable from something else that is still held — a
|
|
38
|
-
* transcript, a rendered mix, a thumbnail. `authored` was
|
|
39
|
-
*
|
|
38
|
+
* transcript, a rendered mix, a thumbnail. `authored` was WRITTEN rather than
|
|
39
|
+
* captured or generated — composed here by a person or an agent, or written
|
|
40
|
+
* elsewhere and brought in: an `.abc` melody, a downloaded deep-search markdown,
|
|
41
|
+
* an imported doc.
|
|
42
|
+
*
|
|
43
|
+
* The "brought in" half used to be the whole definition, and that was too narrow
|
|
44
|
+
* in the direction that mattered most. Composing a melody in this repository
|
|
45
|
+
* produces a file that is not `captured` (no device, no instant) and not
|
|
46
|
+
* `derived` (made from no other artifact) — so under the old wording the very
|
|
47
|
+
* thing this platform exists to make had no origin it could honestly claim.
|
|
48
|
+
* Found 2026-07-31 by writing one.
|
|
40
49
|
*
|
|
41
50
|
* Flattening these three loses the only property that distinguishes an
|
|
42
51
|
* irreplaceable recording from a file that can be rebuilt on demand.
|
|
@@ -77,6 +86,70 @@ export interface CaptureProvenance {
|
|
|
77
86
|
/** Size of the finished file in bytes. */
|
|
78
87
|
bytes?: number;
|
|
79
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* What may be rebuilt, and what may never be.
|
|
91
|
+
*
|
|
92
|
+
* THREE states, never a boolean, and the third one is the point. `unknown` is
|
|
93
|
+
* what an artifact with no recorded `origin` must report — the *provenance
|
|
94
|
+
* incomplete* state. A boolean forces that case into one bucket or the other,
|
|
95
|
+
* and whichever way it falls it lies: `false` refuses to clean up things that
|
|
96
|
+
* are fine, and `true` marks an unrepeatable take as safe to delete. Absence of
|
|
97
|
+
* evidence is its own answer here and has to survive being read.
|
|
98
|
+
*/
|
|
99
|
+
export declare const ARTIFACT_REPLACEABILITY: readonly ["irreplaceable", "regenerable", "unknown"];
|
|
100
|
+
export type ArtifactReplaceability = (typeof ARTIFACT_REPLACEABILITY)[number];
|
|
101
|
+
/**
|
|
102
|
+
* Whether one LEAF may be rebuilt. Pure and local — it reads the artifact it is
|
|
103
|
+
* given and performs no walk.
|
|
104
|
+
*
|
|
105
|
+
* - `captured` is irreplaceable, always. A device, an instant, one chance.
|
|
106
|
+
* - `authored` is irreplaceable UNLESS it names a `sourceArtifact` — an authored
|
|
107
|
+
* file that was brought in from something still held can be brought in again;
|
|
108
|
+
* one composed here cannot.
|
|
109
|
+
* - `derived` is regenerable, which is the whole meaning of the word.
|
|
110
|
+
* - Absent origin is `unknown`. Never guess it from the file extension.
|
|
111
|
+
*
|
|
112
|
+
* Written 2026-07-31 after composing a melody exposed the hole. The rule this
|
|
113
|
+
* platform had adopted — "a set is unrepeatable exactly when it transitively
|
|
114
|
+
* contains a `captured` leaf" — walks a melody folder, finds an `.abc` and its
|
|
115
|
+
* renders, counts zero captured leaves, and reports the set safe to regenerate.
|
|
116
|
+
* The `.abc` is the only thing in it that cannot be remade. The rule was right
|
|
117
|
+
* about recordings and exactly wrong about the composed work this exists for.
|
|
118
|
+
*
|
|
119
|
+
* ## Why a set is refused here rather than answered
|
|
120
|
+
*
|
|
121
|
+
* 0.6.2 typed the parameter `Pick<ArtifactReference, "origin" | "sourceArtifact">`,
|
|
122
|
+
* which an {@link ArtifactSet} satisfies structurally — a set carries `origin`
|
|
123
|
+
* too. A film folder whose manifest said `origin: "derived"` therefore returned
|
|
124
|
+
* `regenerable` without a single member being looked at, and that answer is what
|
|
125
|
+
* authorises deleting a directory holding the only copy of a melody. A set's
|
|
126
|
+
* answer needs a walk; this function does not walk, so it must not answer.
|
|
127
|
+
*
|
|
128
|
+
* Two layers refuse it, because neither alone is enough:
|
|
129
|
+
*
|
|
130
|
+
* 1. **The type.** `kind` is required and must be an {@link ArtifactKind}, and
|
|
131
|
+
* `members` is forbidden. `ArtifactSet` declares `kind?: ArtifactSetKind` and
|
|
132
|
+
* a required `members: string[]`, so it fits neither clause.
|
|
133
|
+
* **This is partial and must be read as partial:** `"other"` belongs to BOTH
|
|
134
|
+
* `ARTIFACT_KINDS` and `ARTIFACT_SET_KINDS`, so a hand-written literal of
|
|
135
|
+
* `{ kind: "other", origin }` carrying no `members` field is indistinguishable
|
|
136
|
+
* from a leaf and still passes. The overlap is deliberate elsewhere and is not
|
|
137
|
+
* worth breaking to close this hole.
|
|
138
|
+
* 2. **The runtime.** A TypeScript type vanishes at the compile step, and the
|
|
139
|
+
* consumer this contract exists for reads plain JavaScript — the whole lesson
|
|
140
|
+
* of 0.6.1. So a value carrying a `members` array is answered `unknown`:
|
|
141
|
+
* provenance not established, because no walk happened. `unknown` is the
|
|
142
|
+
* honest state here for the same reason it exists at all.
|
|
143
|
+
*
|
|
144
|
+
* A caller holding a resolver may compose a set's answer from its members' leaf
|
|
145
|
+
* answers — `irreplaceable` dominates, then `unknown`, and only an all-
|
|
146
|
+
* `regenerable` set is `regenerable`. That walk is deliberately NOT exported:
|
|
147
|
+
* it needs an id-to-artifact resolver this observation-only package cannot
|
|
148
|
+
* supply, and until it can, an exported name would promise more than it does.
|
|
149
|
+
*/
|
|
150
|
+
export declare function artifactReplaceability(artifact: Pick<ArtifactReference, "kind" | "origin" | "sourceArtifact"> & {
|
|
151
|
+
members?: never;
|
|
152
|
+
}): ArtifactReplaceability;
|
|
80
153
|
export interface ArtifactReference {
|
|
81
154
|
id: string;
|
|
82
155
|
kind: ArtifactKind;
|
|
@@ -106,13 +179,25 @@ export interface ArtifactReference {
|
|
|
106
179
|
/**
|
|
107
180
|
* What a set gathers.
|
|
108
181
|
*
|
|
109
|
-
* Composition, Episode, Melody and Film are siblings at the same level —
|
|
110
|
-
* an extension of another, and none is a special case of a recording.
|
|
111
|
-
* is the IAIP folder. Absent means the gathering was observed without
|
|
112
|
-
* classified — an absence, not an error — and `other` is a set whose
|
|
113
|
-
* named a kind this list does not carry yet.
|
|
182
|
+
* Composition, Episode, Melody, Scene and Film are siblings at the same level —
|
|
183
|
+
* none is an extension of another, and none is a special case of a recording.
|
|
184
|
+
* `inquiry` is the IAIP folder. Absent means the gathering was observed without
|
|
185
|
+
* being classified — an absence, not an error — and `other` is a set whose
|
|
186
|
+
* source named a kind this list does not carry yet.
|
|
187
|
+
*
|
|
188
|
+
* `scene` was added 2026-07-31 from William's own sentence: *"Inside of one of
|
|
189
|
+
* my film, there are scenes. And inside of a scene, there is a musical
|
|
190
|
+
* composition. And inside of musical composition, there are multiple melodies.
|
|
191
|
+
* And all of that could be related to an artifact that we captured on the land,
|
|
192
|
+
* or can come from that."* Scene sits between `film` and `composition` in that
|
|
193
|
+
* hierarchy — a film gathers scenes, a scene gathers compositions.
|
|
194
|
+
*
|
|
195
|
+
* The ORDER of this array carries none of that. It is accretion order, and the
|
|
196
|
+
* hierarchy lives in the membership edges (`ArtifactRelation`) where it can
|
|
197
|
+
* differ per film. Reading containment out of this array's index would be
|
|
198
|
+
* reading a fact that was never written.
|
|
114
199
|
*/
|
|
115
|
-
export declare const ARTIFACT_SET_KINDS: readonly ["inquiry", "composition", "episode", "melody", "film", "other"];
|
|
200
|
+
export declare const ARTIFACT_SET_KINDS: readonly ["inquiry", "composition", "scene", "episode", "melody", "film", "other"];
|
|
116
201
|
export type ArtifactSetKind = (typeof ARTIFACT_SET_KINDS)[number];
|
|
117
202
|
/** Narrows an unvalidated string to {@link ArtifactSetKind}. */
|
|
118
203
|
export declare function isArtifactSetKind(value: unknown): value is ArtifactSetKind;
|
|
@@ -142,11 +227,34 @@ export interface ArtifactSet {
|
|
|
142
227
|
kind?: ArtifactSetKind;
|
|
143
228
|
/** How the gathering came to exist; same axis and same absence rule as a leaf. */
|
|
144
229
|
origin?: ArtifactOrigin;
|
|
230
|
+
/**
|
|
231
|
+
* The came-from pointer for the SET, same name and same semantics as on
|
|
232
|
+
* {@link ArtifactReference}: the artifact this gathering was made from.
|
|
233
|
+
*
|
|
234
|
+
* This is what lets a scene say it came from a take captured on the land, and
|
|
235
|
+
* a melody set say it came from the recording someone sang into a phone —
|
|
236
|
+
* William's *"can come from that"*. Without it the origin of a gathering could
|
|
237
|
+
* only be inferred by guessing at its members, which is exactly the guess this
|
|
238
|
+
* package refuses to make.
|
|
239
|
+
*
|
|
240
|
+
* It describes how the SET came to be, and never its members — the same rule
|
|
241
|
+
* `origin` already follows here, where a set's `origin` describes its own
|
|
242
|
+
* manifest and says nothing about what is inside it. A scene derived from a
|
|
243
|
+
* take may hold members that were authored, and neither field contradicts the
|
|
244
|
+
* other. Anything that needs the members' answer must walk them.
|
|
245
|
+
*/
|
|
246
|
+
sourceArtifact?: string;
|
|
145
247
|
label?: string;
|
|
146
248
|
/**
|
|
147
249
|
* Artifact ids gathered here. An empty array is meaningful: `scaffoldVessel`
|
|
148
250
|
* creates a named, empty inquiry directory on purpose, and that emptiness is
|
|
149
251
|
* the state of the inquiry, not missing data.
|
|
252
|
+
*
|
|
253
|
+
* Order carries no guarantee. Nothing may read sequence, priority or time out
|
|
254
|
+
* of this array's index — `observeEpisodeDirectory` re-sorts entries lexically,
|
|
255
|
+
* so a document's own order does not survive the round trip. Where order is
|
|
256
|
+
* meant, it is stated: `SegmentDescriptor` carries an explicit `order: number`
|
|
257
|
+
* precisely so it does not depend on position.
|
|
150
258
|
*/
|
|
151
259
|
members: string[];
|
|
152
260
|
metadata: Record<string, unknown>;
|
|
@@ -168,11 +276,16 @@ export type ArtifactRelationKind = (typeof ARTIFACT_RELATION_KINDS)[number];
|
|
|
168
276
|
export declare function isArtifactRelationKind(value: unknown): value is ArtifactRelationKind;
|
|
169
277
|
/**
|
|
170
278
|
* What can sit on the container end of a membership edge. Composition, Episode,
|
|
171
|
-
* Melody and Film are named at the same level because they are peers
|
|
172
|
-
* root; `artifact-set` covers a gathering whose kind is unclassified,
|
|
173
|
-
* `artifact` lets a set be a member of another set.
|
|
279
|
+
* Melody, Scene and Film are named at the same level because they are peers
|
|
280
|
+
* under one root; `artifact-set` covers a gathering whose kind is unclassified,
|
|
281
|
+
* and `artifact` lets a set be a member of another set.
|
|
282
|
+
*
|
|
283
|
+
* `scene` is named here for the same reason the others are: without it, the edge
|
|
284
|
+
* that puts a composition inside a scene degrades to `artifact-set`, and a
|
|
285
|
+
* reader can no longer tell a scene from any other unclassified gathering — the
|
|
286
|
+
* one relation in William's hierarchy that would have been lost silently.
|
|
174
287
|
*/
|
|
175
|
-
export declare const ARTIFACT_RELATION_TARGET_KINDS: readonly ["episode", "composition", "melody", "film", "artifact-set", "artifact"];
|
|
288
|
+
export declare const ARTIFACT_RELATION_TARGET_KINDS: readonly ["episode", "composition", "scene", "melody", "film", "artifact-set", "artifact"];
|
|
176
289
|
export type ArtifactRelationTargetKind = (typeof ARTIFACT_RELATION_TARGET_KINDS)[number];
|
|
177
290
|
/** Narrows an unvalidated string to {@link ArtifactRelationTargetKind}. */
|
|
178
291
|
export declare function isArtifactRelationTargetKind(value: unknown): value is ArtifactRelationTargetKind;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,iBAAiB,GACzB,oBAAoB,GACpB,WAAW,GACX,oBAAoB,CAAA;AAExB,MAAM,MAAM,mBAAmB,GAC3B,kBAAkB,GAClB,cAAc,GACd,oBAAoB,GACpB,iBAAiB,CAAA;AAErB,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,mBAAmB,CAAA;IAC3B,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,gBAAgB,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAA;IAClD,KAAK,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,cAAc,6EAQhB,CAAA;AAEX,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,cAAc,CAAC,CAAC,MAAM,CAAC,CAAA;AAE1D,6DAA6D;AAC7D,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,YAAY,CAEpE;AAED
|
|
1
|
+
{"version":3,"file":"observation.d.ts","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"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"}
|
package/dist/observation.js
CHANGED
|
@@ -34,8 +34,17 @@ export function isArtifactKind(value) {
|
|
|
34
34
|
* `captured` is unrepeatable: a device, an instant, one chance. A take that is
|
|
35
35
|
* deleted is gone, because the moment it recorded will not happen twice.
|
|
36
36
|
* `derived` is regenerable from something else that is still held — a
|
|
37
|
-
* transcript, a rendered mix, a thumbnail. `authored` was
|
|
38
|
-
*
|
|
37
|
+
* transcript, a rendered mix, a thumbnail. `authored` was WRITTEN rather than
|
|
38
|
+
* captured or generated — composed here by a person or an agent, or written
|
|
39
|
+
* elsewhere and brought in: an `.abc` melody, a downloaded deep-search markdown,
|
|
40
|
+
* an imported doc.
|
|
41
|
+
*
|
|
42
|
+
* The "brought in" half used to be the whole definition, and that was too narrow
|
|
43
|
+
* in the direction that mattered most. Composing a melody in this repository
|
|
44
|
+
* produces a file that is not `captured` (no device, no instant) and not
|
|
45
|
+
* `derived` (made from no other artifact) — so under the old wording the very
|
|
46
|
+
* thing this platform exists to make had no origin it could honestly claim.
|
|
47
|
+
* Found 2026-07-31 by writing one.
|
|
39
48
|
*
|
|
40
49
|
* Flattening these three loses the only property that distinguishes an
|
|
41
50
|
* irreplaceable recording from a file that can be rebuilt on demand.
|
|
@@ -52,18 +61,111 @@ export const ARTIFACT_ORIGINS = Object.freeze(["captured", "derived", "authored"
|
|
|
52
61
|
export function isArtifactOrigin(value) {
|
|
53
62
|
return typeof value === "string" && ARTIFACT_ORIGINS.includes(value);
|
|
54
63
|
}
|
|
64
|
+
/**
|
|
65
|
+
* What may be rebuilt, and what may never be.
|
|
66
|
+
*
|
|
67
|
+
* THREE states, never a boolean, and the third one is the point. `unknown` is
|
|
68
|
+
* what an artifact with no recorded `origin` must report — the *provenance
|
|
69
|
+
* incomplete* state. A boolean forces that case into one bucket or the other,
|
|
70
|
+
* and whichever way it falls it lies: `false` refuses to clean up things that
|
|
71
|
+
* are fine, and `true` marks an unrepeatable take as safe to delete. Absence of
|
|
72
|
+
* evidence is its own answer here and has to survive being read.
|
|
73
|
+
*/
|
|
74
|
+
export const ARTIFACT_REPLACEABILITY = Object.freeze([
|
|
75
|
+
"irreplaceable",
|
|
76
|
+
"regenerable",
|
|
77
|
+
"unknown",
|
|
78
|
+
]);
|
|
79
|
+
/**
|
|
80
|
+
* Whether one LEAF may be rebuilt. Pure and local — it reads the artifact it is
|
|
81
|
+
* given and performs no walk.
|
|
82
|
+
*
|
|
83
|
+
* - `captured` is irreplaceable, always. A device, an instant, one chance.
|
|
84
|
+
* - `authored` is irreplaceable UNLESS it names a `sourceArtifact` — an authored
|
|
85
|
+
* file that was brought in from something still held can be brought in again;
|
|
86
|
+
* one composed here cannot.
|
|
87
|
+
* - `derived` is regenerable, which is the whole meaning of the word.
|
|
88
|
+
* - Absent origin is `unknown`. Never guess it from the file extension.
|
|
89
|
+
*
|
|
90
|
+
* Written 2026-07-31 after composing a melody exposed the hole. The rule this
|
|
91
|
+
* platform had adopted — "a set is unrepeatable exactly when it transitively
|
|
92
|
+
* contains a `captured` leaf" — walks a melody folder, finds an `.abc` and its
|
|
93
|
+
* renders, counts zero captured leaves, and reports the set safe to regenerate.
|
|
94
|
+
* The `.abc` is the only thing in it that cannot be remade. The rule was right
|
|
95
|
+
* about recordings and exactly wrong about the composed work this exists for.
|
|
96
|
+
*
|
|
97
|
+
* ## Why a set is refused here rather than answered
|
|
98
|
+
*
|
|
99
|
+
* 0.6.2 typed the parameter `Pick<ArtifactReference, "origin" | "sourceArtifact">`,
|
|
100
|
+
* which an {@link ArtifactSet} satisfies structurally — a set carries `origin`
|
|
101
|
+
* too. A film folder whose manifest said `origin: "derived"` therefore returned
|
|
102
|
+
* `regenerable` without a single member being looked at, and that answer is what
|
|
103
|
+
* authorises deleting a directory holding the only copy of a melody. A set's
|
|
104
|
+
* answer needs a walk; this function does not walk, so it must not answer.
|
|
105
|
+
*
|
|
106
|
+
* Two layers refuse it, because neither alone is enough:
|
|
107
|
+
*
|
|
108
|
+
* 1. **The type.** `kind` is required and must be an {@link ArtifactKind}, and
|
|
109
|
+
* `members` is forbidden. `ArtifactSet` declares `kind?: ArtifactSetKind` and
|
|
110
|
+
* a required `members: string[]`, so it fits neither clause.
|
|
111
|
+
* **This is partial and must be read as partial:** `"other"` belongs to BOTH
|
|
112
|
+
* `ARTIFACT_KINDS` and `ARTIFACT_SET_KINDS`, so a hand-written literal of
|
|
113
|
+
* `{ kind: "other", origin }` carrying no `members` field is indistinguishable
|
|
114
|
+
* from a leaf and still passes. The overlap is deliberate elsewhere and is not
|
|
115
|
+
* worth breaking to close this hole.
|
|
116
|
+
* 2. **The runtime.** A TypeScript type vanishes at the compile step, and the
|
|
117
|
+
* consumer this contract exists for reads plain JavaScript — the whole lesson
|
|
118
|
+
* of 0.6.1. So a value carrying a `members` array is answered `unknown`:
|
|
119
|
+
* provenance not established, because no walk happened. `unknown` is the
|
|
120
|
+
* honest state here for the same reason it exists at all.
|
|
121
|
+
*
|
|
122
|
+
* A caller holding a resolver may compose a set's answer from its members' leaf
|
|
123
|
+
* answers — `irreplaceable` dominates, then `unknown`, and only an all-
|
|
124
|
+
* `regenerable` set is `regenerable`. That walk is deliberately NOT exported:
|
|
125
|
+
* it needs an id-to-artifact resolver this observation-only package cannot
|
|
126
|
+
* supply, and until it can, an exported name would promise more than it does.
|
|
127
|
+
*/
|
|
128
|
+
export function artifactReplaceability(artifact) {
|
|
129
|
+
// The type is gone by now. A JavaScript caller can still hand us a set, and
|
|
130
|
+
// the leaf answer for a set is the one that gets a folder deleted.
|
|
131
|
+
if (Array.isArray(artifact.members))
|
|
132
|
+
return "unknown";
|
|
133
|
+
switch (artifact.origin) {
|
|
134
|
+
case "captured":
|
|
135
|
+
return "irreplaceable";
|
|
136
|
+
case "derived":
|
|
137
|
+
return "regenerable";
|
|
138
|
+
case "authored":
|
|
139
|
+
return artifact.sourceArtifact ? "regenerable" : "irreplaceable";
|
|
140
|
+
default:
|
|
141
|
+
return "unknown";
|
|
142
|
+
}
|
|
143
|
+
}
|
|
55
144
|
/**
|
|
56
145
|
* What a set gathers.
|
|
57
146
|
*
|
|
58
|
-
* Composition, Episode, Melody and Film are siblings at the same level —
|
|
59
|
-
* an extension of another, and none is a special case of a recording.
|
|
60
|
-
* is the IAIP folder. Absent means the gathering was observed without
|
|
61
|
-
* classified — an absence, not an error — and `other` is a set whose
|
|
62
|
-
* named a kind this list does not carry yet.
|
|
147
|
+
* Composition, Episode, Melody, Scene and Film are siblings at the same level —
|
|
148
|
+
* none is an extension of another, and none is a special case of a recording.
|
|
149
|
+
* `inquiry` is the IAIP folder. Absent means the gathering was observed without
|
|
150
|
+
* being classified — an absence, not an error — and `other` is a set whose
|
|
151
|
+
* source named a kind this list does not carry yet.
|
|
152
|
+
*
|
|
153
|
+
* `scene` was added 2026-07-31 from William's own sentence: *"Inside of one of
|
|
154
|
+
* my film, there are scenes. And inside of a scene, there is a musical
|
|
155
|
+
* composition. And inside of musical composition, there are multiple melodies.
|
|
156
|
+
* And all of that could be related to an artifact that we captured on the land,
|
|
157
|
+
* or can come from that."* Scene sits between `film` and `composition` in that
|
|
158
|
+
* hierarchy — a film gathers scenes, a scene gathers compositions.
|
|
159
|
+
*
|
|
160
|
+
* The ORDER of this array carries none of that. It is accretion order, and the
|
|
161
|
+
* hierarchy lives in the membership edges (`ArtifactRelation`) where it can
|
|
162
|
+
* differ per film. Reading containment out of this array's index would be
|
|
163
|
+
* reading a fact that was never written.
|
|
63
164
|
*/
|
|
64
165
|
export const ARTIFACT_SET_KINDS = Object.freeze([
|
|
65
166
|
"inquiry",
|
|
66
167
|
"composition",
|
|
168
|
+
"scene",
|
|
67
169
|
"episode",
|
|
68
170
|
"melody",
|
|
69
171
|
"film",
|
|
@@ -84,13 +186,19 @@ export function isArtifactRelationKind(value) {
|
|
|
84
186
|
}
|
|
85
187
|
/**
|
|
86
188
|
* What can sit on the container end of a membership edge. Composition, Episode,
|
|
87
|
-
* Melody and Film are named at the same level because they are peers
|
|
88
|
-
* root; `artifact-set` covers a gathering whose kind is unclassified,
|
|
89
|
-
* `artifact` lets a set be a member of another set.
|
|
189
|
+
* Melody, Scene and Film are named at the same level because they are peers
|
|
190
|
+
* under one root; `artifact-set` covers a gathering whose kind is unclassified,
|
|
191
|
+
* and `artifact` lets a set be a member of another set.
|
|
192
|
+
*
|
|
193
|
+
* `scene` is named here for the same reason the others are: without it, the edge
|
|
194
|
+
* that puts a composition inside a scene degrades to `artifact-set`, and a
|
|
195
|
+
* reader can no longer tell a scene from any other unclassified gathering — the
|
|
196
|
+
* one relation in William's hierarchy that would have been lost silently.
|
|
90
197
|
*/
|
|
91
198
|
export const ARTIFACT_RELATION_TARGET_KINDS = Object.freeze([
|
|
92
199
|
"episode",
|
|
93
200
|
"composition",
|
|
201
|
+
"scene",
|
|
94
202
|
"melody",
|
|
95
203
|
"film",
|
|
96
204
|
"artifact-set",
|
package/dist/observation.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"observation.js","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuBH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,OAAO;IACP,YAAY;IACZ,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;CACC,CAAC,CAAA;AAIX,6DAA6D;AAC7D,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,cAAoC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC3F,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"observation.js","sourceRoot":"","sources":["../src/observation.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAuBH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1C,OAAO;IACP,YAAY;IACZ,OAAO;IACP,MAAM;IACN,MAAM;IACN,OAAO;IACP,OAAO;CACC,CAAC,CAAA;AAIX,6DAA6D;AAC7D,MAAM,UAAU,cAAc,CAAC,KAAc;IAC3C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,cAAoC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC3F,CAAC;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,UAAU,EAAE,SAAS,EAAE,UAAU,CAAU,CAAC,CAAA;AAI3F;;;;;;;GAOG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAc;IAC7C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,gBAAsC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC7F,CAAC;AA4BD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,CAAC;IACnD,eAAe;IACf,aAAa;IACb,SAAS;CACD,CAAC,CAAA;AAIX;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,MAAM,UAAU,sBAAsB,CACpC,QAEC;IAED,4EAA4E;IAC5E,mEAAmE;IACnE,IAAI,KAAK,CAAC,OAAO,CAAE,QAAkC,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAA;IAEhF,QAAQ,QAAQ,CAAC,MAAM,EAAE,CAAC;QACxB,KAAK,UAAU;YACb,OAAO,eAAe,CAAA;QACxB,KAAK,SAAS;YACZ,OAAO,aAAa,CAAA;QACtB,KAAK,UAAU;YACb,OAAO,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAA;QAClE;YACE,OAAO,SAAS,CAAA;IACpB,CAAC;AACH,CAAC;AA6BD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,CAAC;IAC9C,SAAS;IACT,aAAa;IACb,OAAO;IACP,SAAS;IACT,QAAQ;IACR,MAAM;IACN,OAAO;CACC,CAAC,CAAA;AAIX,gEAAgE;AAChE,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,kBAAwC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AAC/F,CAAC;AAsED;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,WAAW,EAAE,SAAS,CAAU,CAAC,CAAA;AAIvF,qEAAqE;AACrE,MAAM,UAAU,sBAAsB,CAAC,KAAc;IACnD,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAK,uBAA6C,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;AACpG,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,8BAA8B,GAAG,MAAM,CAAC,MAAM,CAAC;IAC1D,SAAS;IACT,aAAa;IACb,OAAO;IACP,QAAQ;IACR,MAAM;IACN,cAAc;IACd,UAAU;CACF,CAAC,CAAA;AAIX,2EAA2E;AAC3E,MAAM,UAAU,4BAA4B,CAC1C,KAAc;IAEd,OAAO,CACL,OAAO,KAAK,KAAK,QAAQ;QACxB,8BAAoD,CAAC,QAAQ,CAAC,KAAK,CAAC,CACtE,CAAA;AACH,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miadi/episodic-memory-schema",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "TypeScript types and JSON Schema for episodic memory — the durable session-to-session memory layer in the Miadi orchestration kit. Narrative layer is NCP-aligned; provenance layer is W3C PROV-DM and OAIS-informed.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"miadi",
|