@ai-matrx/records 0.60.7 → 0.60.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,42 @@
1
1
  # Changelog — @ai-matrx/records
2
2
 
3
+ <!-- matrx-auto-git-docs-resolution-needed-delete-this-when-resolved — two versions follow: LOCAL first, then GITHUB. (LOCAL latest 2026-10-02 14:57; GITHUB latest 2026-10-02 14:58; LOCAL lacks 1 of GITHUB's 3 new lines; GITHUB lacks 17 of LOCAL's 17 new lines; recover: git show e40bf4695b:'apps/shared/records/CHANGELOG.md' / 5b7bf04c07:'apps/shared/records/CHANGELOG.md') Delete these three marker lines when resolved. -->
4
+
5
+ ## 0.60.9
6
+
7
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
8
+ `git diff npm/records/v0.60.7..npm/records/v0.60.9 -- apps/shared/records`).
9
+ No source changes intended and no consumer action required.
10
+
11
+ ## 0.61.0
12
+
13
+ Lane PLATFORM-APP-DATA (asked by lane KINDS-GLUE, board items L12-1 … L12-7) — `ensureTable` makes the
14
+ tables an app keeps.
15
+
16
+ - **Placement, kind and drafts facts are stored.** `NewTableSpec` takes `keptByTheApp`, `keptFor`, `kind`,
17
+ `draftsFor`, `draftsStamp`; they are written on the table `ensureTable` (and `declareTable`) makes.
18
+ - **`keptFor` is part of the address.** `ensureTable` finds a table by slug AND `keptFor`: a person's table and
19
+ an app's table of the same slug are different tables (`custom.table_ensure`, lane12_f).
20
+ - **`homeId`.** A new table can be put in an existing Home the caller may change; no second Home is made. A Home
21
+ that is not in this organization (or archived, or not hers to change) is refused and nothing is made.
22
+ - **Full column declarations.** `NewFieldSpec.optionsTableId` reuses an existing choice list (sent as
23
+ `config.options_table_id`); `NewFieldSpec.declaration` passes any other `custom.field_declare` key through
24
+ verbatim, applied last.
25
+ - Proven on the clone as admin@admin.com and test@test.com: a 48-character slug, and a server path declaring the
26
+ code tier (`app.actor_tier = system`) acting as the person, both work. `drift` is unchanged.
27
+ - `custom.table_find` now asks the record-store switch first (lane12_one_table_is_found_by_its_slug).
28
+
29
+ Consumer action: none required. Needs `lane12_f_an_ensured_table_finds_its_kept_for_and_takes_a_home.sql` on
30
+ production for `keptFor` matching and `homeId`; before it, `homeId` is ignored (a Home is made) and matching
31
+ is by slug alone.
32
+ <!-- matrx-auto-git-docs-resolution-needed-delete-this-when-resolved — GITHUB version below -->
33
+ ## 0.60.8
34
+
35
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
36
+ `git diff npm/records/v0.60.7..npm/records/v0.60.8 -- apps/shared/records`).
37
+ No source changes intended and no consumer action required.
38
+ <!-- matrx-auto-git-docs-resolution-needed-delete-this-when-resolved — end of both versions -->
39
+
3
40
  ## 0.60.7
4
41
 
5
42
  Automatic changed-only republish (docs/metadata drift since the last tag — see
package/README.md CHANGED
@@ -73,6 +73,32 @@ not be read; `declared` is the store's sentence). It is `[]` on a birth and when
73
73
  it, so `long_text` is never a false `type` drift. This shape is the contract a release-time drift
74
74
  check reads (`parseFieldDrift` types a raw answer).
75
75
 
76
+ ### A table the app keeps
77
+
78
+ ```ts
79
+ const outputs = await ensureTable(records, {
80
+ name: "Exercise flashcard outputs", slug: "agent_output_exercise_flashcard",
81
+ keptByTheApp: true, keptFor: "agent_output", kind: "exercise_flashcard",
82
+ homeId: sharedOutputsHome, // a NEW table goes in this Home; none is made
83
+ fields: [{ key: "body_region", label: "Body region", type: "select", optionsTableId }],
84
+ });
85
+ ```
86
+
87
+ `keptFor` is part of the address: a spec carrying it finds only a table kept for that word, and a spec
88
+ without it never finds an app's table — a person's table and an app's table of one slug are different
89
+ tables. `keptByTheApp`, `keptFor`, `kind`, `draftsFor` and `draftsStamp` are stored on the table it
90
+ makes. `homeId` must be a live Home of this organization the caller may change, or nothing is made.
91
+ `optionsTableId` reuses an existing choice list; `declaration` passes any other `custom.field_declare`
92
+ key through as written.
93
+
94
+ ### When two tables share a slug, `tableFind` and `ensureTable` may differ
95
+
96
+ A slug is not unique (older organizations hold a few duplicates). `tableFind` answers the oldest
97
+ table of that slug **the caller may see**. `ensureTable` takes the oldest table of that slug
98
+ **overall** and, if the caller may not know that one, refuses with the read door's own words rather
99
+ than making a second table. So for a hidden oldest duplicate, `tableFind` returns a newer table while
100
+ `ensureTable` refuses; both always agree when the caller can see the oldest one.
101
+
76
102
  Nothing here throws, and nothing here invents an answer. A door the store does
77
103
  not have yet is answered `door_absent`, naming the door AND the lane that owes
78
104
  it — `fieldPropose`, `tablePropose` and `mergeFieldResolve`
@@ -44506,7 +44506,9 @@ function fieldDeclarationFor(field) {
44506
44506
  ...field.unit ? { unit: field.unit } : {},
44507
44507
  ...field.kind ? { kind: field.kind } : {},
44508
44508
  ...field.allowedTypes ? { allowed_types: field.allowedTypes } : {},
44509
- ...field.unique ? { rules: [{ kind: "unique" }] } : {}
44509
+ ...field.unique ? { rules: [{ kind: "unique" }] } : {},
44510
+ ...field.optionsTableId ? { config: { ...field.config ?? {}, options_table_id: field.optionsTableId } } : {},
44511
+ ...field.declaration ?? {}
44510
44512
  };
44511
44513
  }
44512
44514
  function tableSpecFor(spec, fields, slug) {
@@ -44526,14 +44528,23 @@ function tableSpecFor(spec, fields, slug) {
44526
44528
  // AGT-1: a table a person made is agent-writable by declaration; the
44527
44529
  // organization turns it off, never this package.
44528
44530
  agent_writable: true,
44529
- default_sort: [{ field: titleField, direction: "asc" }]
44531
+ default_sort: [{ field: titleField, direction: "asc" }],
44532
+ ...spec.keptByTheApp !== void 0 ? { kept_by_the_app: spec.keptByTheApp } : {},
44533
+ ...spec.keptFor ? { kept_for: spec.keptFor } : {},
44534
+ ...spec.kind ? { kind: spec.kind } : {},
44535
+ ...spec.draftsFor ? { drafts_for: spec.draftsFor } : {},
44536
+ ...spec.draftsStamp ? { drafts_stamp: spec.draftsStamp } : {}
44530
44537
  };
44531
44538
  }
44532
44539
  async function ensureTable(client, spec) {
44533
44540
  const fields = spec.fields && spec.fields.length > 0 ? spec.fields : DEFAULT_FIELDS;
44534
44541
  const slug = spec.slug ?? tokenFor(spec.name);
44535
44542
  const ensured = await client.tableEnsure({
44536
- spec: { ...tableSpecFor(spec, fields, slug), fields: fields.map(fieldDeclarationFor) }
44543
+ spec: {
44544
+ ...tableSpecFor(spec, fields, slug),
44545
+ ...spec.homeId ? { home_id: spec.homeId } : {},
44546
+ fields: fields.map(fieldDeclarationFor)
44547
+ }
44537
44548
  });
44538
44549
  if (!ensured.ok) return ensured;
44539
44550
  return {