@polycode-projects/the-mechanical-code-talker 6.0.21 → 7.0.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.
Files changed (36) hide show
  1. package/README.md +5 -15
  2. package/bin/tmct.mjs +8 -3
  3. package/package.json +1 -5
  4. package/src/adapters/memory/core.mjs +108 -96
  5. package/src/domain/agent-traits.mjs +1 -1
  6. package/src/domain/answer-variants.json +1 -1
  7. package/src/domain/cli-verbs.mjs +1 -0
  8. package/src/domain/memory/causal-stability.mjs +22 -5
  9. package/src/domain/memory/fact-order.mjs +3 -3
  10. package/src/domain/memory/provenance-time.mjs +35 -0
  11. package/src/domain/memory/retraction.mjs +3 -5
  12. package/src/domain/memory/trust.mjs +11 -11
  13. package/src/domain/news-feed.mjs +1 -1
  14. package/src/domain/seeded-random.mjs +6 -6
  15. package/src/services/adventure.mjs +10 -41
  16. package/src/services/chat-page-viz.mjs +12 -1111
  17. package/src/services/chat-session.mjs +20 -6
  18. package/src/services/chat.mjs +269 -197
  19. package/src/services/extract-facts.mjs +1 -1
  20. package/src/services/import-file.mjs +1 -1
  21. package/src/services/mud-viz.mjs +21 -1082
  22. package/src/services/mudiii-viz.mjs +0 -4
  23. package/src/services/pill-complete.mjs +5 -8
  24. package/src/services/predator-prey.mjs +3 -5
  25. package/src/surfaces/web/memory-ask-browser.bundle.js +107 -107
  26. package/src/surfaces/web/mud-browser-entry.mjs +8 -48
  27. package/test-benchmarks/agentbench/README.md +7 -10
  28. package/src/adapters/p2p/webrtc-transport.mjs +0 -169
  29. package/src/domain/p2p/facts.mjs +0 -102
  30. package/src/domain/p2p/peer-id.mjs +0 -47
  31. package/src/domain/p2p/provenance-relabel.mjs +0 -37
  32. package/src/domain/p2p/sync-filter.mjs +0 -43
  33. package/src/domain/p2p/wire.mjs +0 -126
  34. package/src/services/p2p-room.mjs +0 -848
  35. package/src/services/share-overlay-viz.mjs +0 -623
  36. package/src/surfaces/web/p2p-browser-entry.mjs +0 -39
@@ -0,0 +1,35 @@
1
+ // memory/provenance-time.mjs — reading "when" off a fact's provenance tag.
2
+ //
3
+ // A fact's provenance is a " | "-joined union of tags, because appendFacts
4
+ // unions a fresh tag onto the SAME fact id when a triple is asserted again
5
+ // rather than minting a second row. So "when was this most recently true" is a
6
+ // question about the newest segment, not about the string as a whole.
7
+ import { provenanceTagToSource } from "./trust.mjs";
8
+
9
+ /** The newest asserted-at timestamp across every segment of `provenance`, in
10
+ * milliseconds. Null when no segment parses to a timestamp at all. */
11
+ export function latestProvenanceTimestamp(provenance) {
12
+ const tag = String(provenance || "");
13
+ if (!tag) return null;
14
+ let latest = null;
15
+ for (const segment of tag.split(" | ")) {
16
+ const source = provenanceTagToSource(segment);
17
+ const at = source?.createdAt ? Date.parse(source.createdAt) : NaN;
18
+ if (!Number.isNaN(at) && (latest === null || at > latest)) latest = at;
19
+ }
20
+ return latest;
21
+ }
22
+
23
+ /** The latest-by-timestamp row for a subject+predicate pair — the "current
24
+ * value" read for an add-only fact that is never retracted. A first-wins read
25
+ * takes the oldest of these instead. */
26
+ export function latestFact(rows, subject, predicate) {
27
+ let best = null;
28
+ let bestAt = -Infinity;
29
+ for (const row of rows) {
30
+ if (row.subject !== subject || row.predicate !== predicate) continue;
31
+ const at = latestProvenanceTimestamp(row.provenance) ?? -Infinity;
32
+ if (at > bestAt) { best = row; bestAt = at; }
33
+ }
34
+ return best;
35
+ }
@@ -23,17 +23,15 @@
23
23
  // Max is a join too, so that field merges in either order and agrees.
24
24
  //
25
25
  // Pure: this module plans, merges and encodes retraction RECORDS. core.mjs owns
26
- // the store, p2p-room.mjs owns the wire. Its own class, its own id suffix and
27
- // its own predicate keep it clear of compaction — a compacted record and a
26
+ // the store. Its own class, its own id suffix and its own predicate keep it
27
+ // clear of compaction — a compacted record and a
28
28
  // retracted one mean opposite things, and one namespace would let a summary
29
29
  // read as a tombstone. The CRDT vocabulary above is pinned in
30
30
  // docs/references/papers/crdt.md.
31
31
 
32
32
  export const RETRACTION_CLASS = "Retraction";
33
33
 
34
- /** The predicate a retraction travels under. The sync filters admit it on its
35
- * own, because a retraction has to cross a wire that a chat room gates on
36
- * provenance kind and a mud room gates on world predicates. */
34
+ /** The predicate a retraction travels under. */
37
35
  export const RETRACTION_PREDICATE = "mgx:retracted";
38
36
 
39
37
  export const RETRACTED_RECORD_IDS_PROP = "mgx:retractedRecordIds";
@@ -33,12 +33,12 @@ function parseChatTagRest(rest) {
33
33
  const PEER_NODE_MARKER = "#node:";
34
34
  const PEER_TAG_PREFIX = "peer:";
35
35
 
36
- /** `peer:<displayName>#node:<nodeId>@<ts>` — the wire shape a broadcasting peer
37
- * relabels its own teach/operator tags into. The node id is the origin's
38
- * stable identity and the only part that keys the Source; the display name is
36
+ /** `peer:<displayName>#node:<nodeId>@<ts>` — the shape a tag takes when it
37
+ * names the node that authored it. The node id is the origin's stable
38
+ * identity and the only part that keys the Source; the display name is
39
39
  * user-chosen, mutable and collidable, so it records who to SHOW, not who it
40
40
  * is — the same discipline `child:`'s term and `world:`'s turn segments hold.
41
- * Null for anything without the segment, so an older peer tag falls through to
41
+ * Null for anything without the segment, so a tag missing it falls through to
42
42
  * the plain teach parse unchanged. */
43
43
  function parsePeerNodeTagRest(rest) {
44
44
  if (!rest.startsWith(PEER_TAG_PREFIX)) return null;
@@ -79,11 +79,11 @@ function parsePeerNodeTagRest(rest) {
79
79
  * teach:chat:<session>@<ts> -> { kind:"teach", createdAt:<ts>, sessionId:<session> }
80
80
  * teach:peer:<name>#node:<id>@<ts>
81
81
  * -> { kind:"teachNode", nodeId:<id>, displayName:<name>, createdAt:<ts> }
82
- * (a peer's own tag, relabeled for the wire by whichever node authored it.
83
- * The node id keys the Source; the display name is presentation only. A
84
- * peer tag with no `#node:` segment predates the segment and parses as a
85
- * plain "teach" whose session slot is the whole name — which is what lets
86
- * old and new readers share one wire.)
82
+ * (a tag another node authored. The node id keys the Source; the display
83
+ * name is presentation only, so two nodes that chose the same name stay
84
+ * separate Sources. A tag with no `#node:` segment predates the segment
85
+ * and parses as a plain "teach" whose session slot is the whole name, so
86
+ * a store holding both shapes reads both.)
87
87
  * web:<url> | url:<url> -> { kind:"web", url:<url> }
88
88
  * reference:<pack>:<article>[@revid] -> { kind:"reference", pack, article }
89
89
  * (split on the first two colons only; the article keeps any @revid and
@@ -198,8 +198,8 @@ export function provenanceTagToSource(tag) {
198
198
  }
199
199
  if (head.startsWith("teach:")) {
200
200
  const rest = head.slice("teach:".length);
201
- // teach:peer:<name>#node:<id>@<ts> — a peer's own relabeled tag off the
202
- // wire, keyed on the node id rather than the name beside it.
201
+ // teach:peer:<name>#node:<id>@<ts> — a tag another node authored, keyed on
202
+ // the node id rather than the name beside it.
203
203
  const peerNode = parsePeerNodeTagRest(rest);
204
204
  if (peerNode) return peerNode;
205
205
  // the chat teach lane's natural frames — chat.mjs's teachProvenanceTag
@@ -2,7 +2,7 @@
2
2
  // sub-graphs, assemble news items, and render the fixed paraphrase paragraph
3
3
  // (PLAN_NEWS_FEED.md sections 8.2-8.3). Pure throughout: no clock, no I/O, no
4
4
  // reliance on the caller's row order — feeding one fact set in two different
5
- // orders yields byte-identical items, the same discipline p2p-room.mjs's
5
+ // orders yields byte-identical items, the same discipline rows.mjs's
6
6
  // sortFactIndividualsById holds for a CRDT-merged fact set.
7
7
 
8
8
  import { sha256Bytes, normFactTerm } from "./hash.mjs";
@@ -3,12 +3,12 @@
3
3
  // it. Both are pure arithmetic (no I/O, no imports), so a seed reproduces the
4
4
  // same sequence on every machine and every run.
5
5
  //
6
- // The bench case generators (infbench, chatbench's graded pool) draw their
7
- // committed fixtures through these, so the byte sequence they produce is part of
8
- // those artifacts' identity: two callers on one seed must shuffle identically or
9
- // the committed cases.jsonl / graded pool drift. That is the same reason the
10
- // content-address hashes live once in hash.mjs beside this file — a deterministic
11
- // primitive shared across writers has exactly one definition.
6
+ // The bench case generators (infbench) draw their committed fixtures through
7
+ // these, so the byte sequence they produce is part of those artifacts' identity:
8
+ // two callers on one seed must shuffle identically or the committed cases.jsonl
9
+ // drifts. That is the same reason the content-address hashes live once in
10
+ // hash.mjs beside this file — a deterministic primitive shared across writers has
11
+ // exactly one definition.
12
12
 
13
13
  /** mulberry32 PRNG — small, seedable, deterministic across platforms. */
14
14
  export function mulberry32(seed) {
@@ -181,13 +181,13 @@ async function resumedPosition(memoryDir) {
181
181
 
182
182
  // ---- the world-state fold ----------------------------------------------------
183
183
 
184
- /** Which run of the world a store is on. Recasting a shared world (mud.html's
184
+ /** Which run of the world a store is on. Recasting a world (mud.html's
185
185
  * RESET, a slider, the scenario dropdown) reopens the same deterministic
186
- * instance ids over a fresh store while peers may still hold the old run's
187
- * snapshots — this marker is how every reader agrees the world has started
188
- * over. It is an ordinary add-only fact: each recast appends a larger value,
189
- * the fold takes the max, and merging two peers' stores converges because max
190
- * is order-free. */
186
+ * instance ids over a fresh store, so the old run's snapshots can still be
187
+ * sitting in a store somewhere — this marker is how every reader agrees the
188
+ * world has started over. It is an ordinary add-only fact: each recast
189
+ * appends a larger value, the fold takes the max, and merging two stores
190
+ * converges because max is order-free. */
191
191
  export const WORLD_EPOCH_PREDICATE = "mgx:world-epoch";
192
192
  const WORLD_EPOCH_SUBJECT = "world";
193
193
 
@@ -257,36 +257,6 @@ export function worldActionRows(rows) {
257
257
  });
258
258
  }
259
259
 
260
- // The predicates a played turn can write. Every one of them already exists
261
- // above as a private constant; this set is the one place they are gathered so
262
- // a caller outside this file can ask "is this fact part of the live world"
263
- // without learning each name. rdf:type and the display name earn their place
264
- // alongside the folded ones: a dug room and a dug object are minted mid-play,
265
- // and a reader that never receives their class or their plain name cannot draw
266
- // them at all.
267
- const MUD_STATE_PREDICATES = new Set([
268
- ...PLACEMENT_PREDICATES,
269
- ...POSITION_PREDICATES,
270
- OPEN_PREDICATE,
271
- MASS_PREDICATE,
272
- KNOWS_ABOUT_PREDICATE,
273
- DISPLAY_NAME_PREDICATE,
274
- "rdf:type",
275
- // Which run the world is on IS live world state: a peer that misses the
276
- // recast marker keeps folding the old run's snapshots as current.
277
- WORLD_EPOCH_PREDICATE,
278
- ]);
279
-
280
- /** Whether `predicate` carries live world state — where a thing stands, what
281
- * it weighs, whether it is open, what somebody knows, which way a room leads,
282
- * and the class and name a dug thing is minted with. The P2P sync filter
283
- * reads this to tell a fact a turn produced from the page chrome around it.
284
- * Pure. */
285
- export function isMudStatePredicate(predicate) {
286
- const p = String(predicate || "");
287
- return MUD_STATE_PREDICATES.has(p) || EXIT_PREDICATE_RE.test(p);
288
- }
289
-
290
260
  /** Every individual the world names — its rooms, its cast, its props, and
291
261
  * anything dug up since — as the plain id strings a parser has to have
292
262
  * DECLARED before it can resolve them. @turnN snapshots are skipped: a
@@ -308,7 +278,7 @@ export function worldIndividualNames(rows) {
308
278
  * stored), and the epoch itself.
309
279
  *
310
280
  * Rows rank by the (epoch, turn) pair, so a recast can never be outranked by
311
- * the run it replaced: a peer's turn-9 snapshot from before the recast loses
281
+ * the run it replaced: a turn-9 snapshot from before the recast loses
312
282
  * to a turn-1 snapshot written after it. Base rows carry no stamp of their
313
283
  * own and rank as turn 0 of the CURRENT epoch — a recast re-seeds the same
314
284
  * deterministic ids, so the shard's own rows are exactly the state the new
@@ -653,10 +623,9 @@ async function writeWorldTurn(memoryDir, world, k, facts, cache) {
653
623
  // the last carrot appends a SECOND claim to the same edge, tagged `:gone`, and
654
624
  // appendFacts unions the two tags onto the one fact exactly as it unions any
655
625
  // repeat assertion. "The carrot was here on turn 2" and "the carrot is gone on
656
- // turn 5" are both true; the reader's job is to say which one rules, the same
657
- // recency question the p2p layer asks of its own tags. So reading knowledge
658
- // back means reading the newest claim per edge, never the union of every claim
659
- // ever made.
626
+ // turn 5" are both true; the reader's job is to say which one rules. So
627
+ // reading knowledge back means reading the newest claim per edge, never the
628
+ // union of every claim ever made.
660
629
 
661
630
  const VOIDED_TESTIMONY_SUFFIX = ":gone";
662
631