Skip to content

Commit 22c2d6f

Browse files
feat(spec)!: an agent's memory contract states exactly what the runtime honours — maxEntries and reflectionInterval are required once long-term memory is enabled, longTerm.store is retired, and the block is live (#21413)
Part of #20274 Clause-②: yes (narrowing) ## What this does Ruling of record 5950198150 (director batch #268 item 4, letter A′, maintainer 「同意」): **the `agent.memory` contract states exactly what the runtime honours.** One PR, as the ruling's execution parameters say: the refinement, the `store` retirement, the row flip, the describes. The claim amendment 5951618837 adds the two agent-form help texts, made after PR #21398 landed on `main`. - **The contract check.** `checkAgentMemoryContract` in `packages/spec/src/ai/agent.zod.ts` is a refinement on `memory`, because `reflectionInterval` is `longTerm`'s sibling. It raises one `custom` issue at the key's own path in each of three cases, and each message names the key, its path and the remedy: - `longTerm.enabled: true` without `longTerm.maxEntries` is refused at `memory.longTerm.maxEntries`. - `longTerm.enabled: true` without `reflectionInterval` is refused at `memory.reflectionInterval`. This is the most natural declaration, `{ enabled: true, maxEntries: 5 }`, which cloud refused at turn time. - `reflectionInterval` while `longTerm` is absent or not enabled is refused at `memory.reflectionInterval`. - No default is declared for either number. The check runs only on a body the shape already accepted, so an unknown key, a wrong type or the `store` tombstone gets its own complaint and nothing on top of it. - **`longTerm.store` retires as a whole key,** by the `spec-property-retirement` playbook: - **Tombstone.** `retiredKey()` carries the prescription: "the memory store is platform infrastructure, not agent metadata … Delete the key", closing with the house `os migrate meta --from 17` sentence. `tsc` refuses the key as well. - **Aliases.** The `backend` / `storage` / `provider` aliases pointed at `store`. They moved to `guidance` and carry the same answer, because an alias may not target a tombstone (`alias-integrity.test.ts`). - **D2 conversion `agent-memory-long-term-store-removed`.** Step 18, `retiredFromLoadPath`, `retiredAfter` 17.6.0, order 56. It deletes the key from `agents[].memory.longTerm`, losslessly, with one notice per agent. It supplies neither number. The fixture covers `database`, the materialized `vector` default and `redis`, for 3 notices, plus two untouched controls. - **Registration.** `RETIRED_KEYS_BY_MAJOR[18]` gains the nested `ai/Agent:memory.longTerm.store`. The entry file is `18.ai__Agent__memory.longTerm.store.ts`, and the generated region was written by `gen:migration-registry`. - **D3 entry `agent-memory-store-retired-and-limits-required`.** Its `conversionIds` names the D2. It carries the judgement no conversion can make: the two numbers an enabled `longTerm` now requires. Its `STEP18_RATIONALE` fragment is at order 61. - **`acceptRetiredDefaultResidue` is deliberately not adopted** for the old `vector` default. The measured producer census is zero, and the ruling's ② names the prescription as the backstop for the unmeasured tenant population. The replayed D2 heals stored rows and built artifacts. The reasoning is in the retired-key entry file. - **Ledger.** `agent.memory` moves `experimental` → `live`, with `evidenceScope: cross-repo` and `verifiedAt` 2026-10-02. - The evidence is quoted from the `repo:cloud#1` seat's reading 5946891697 of cloud `ef5a4344`: the reader `agent-runtime.ts#compileAgentMemory` (via `AgentRuntime.resolveTurnGuardrails`), the enforcement in `ai-service.ts`, and the store `agent-memory.ts#AgentMemoryStore`. - The note attributes all of it to that reading. No seat in this session read cloud. - **The window, stated in the note.** At `ef5a4344` the reader still reads `store`: it honours `database` only and refuses `vector` and `redis`. Per the ruling, cloud drops `store` in that one reader once this release reaches its pin, and no earlier. - `state-counts/agent.md` was regenerated by `gen:liveness-counts`: live 22 → 23, experimental 2 → 1. - **Describes.** - `memory` drops `[EXPERIMENTAL — not enforced]`, in the `guardrails` / `structuredOutput` wording: enforced by the cloud AI runtime, and the open framework edition does not run agents. - `longTerm`, `enabled`, `maxEntries` and `reflectionInterval` each state what the runtime does with them: the newest N notes are recalled, a note is written every N delivered interactions, and notes beyond N are evicted. - The NOTE comment's "forward-looking" is replaced by what is enforced. - **The agent form.** - The `memory` row's help text no longer names short-term memory, which is refused. It now states what memory does and that both numbers are required once long-term memory is enabled. - The `planning` row's help text names only `maxIterations`. - `pnpm i18n:extract` regenerated the `en` leaves, run against a spec rebuilt from this tree. The `zh-CN`, `ja-JP` and `es-ES` leaves are authored, not copied. - **The published JSON Schema.** A value-conditioned requirement is not in the finite projection list: `dependent-required` is presence-only, and `refinement-projection.ts` says a value rule stays dropped. So the new site is annotated as dropped. `dropped-refinements.baseline.json` gains `memory` under `ai/Agent` and under the four installed-package schemas that embed agents, which is 5 sites (635 → 640). This is the corrected entry the build printed. - **Regenerated:** `content/docs/references/ai/agent.mdx`. - **Changeset:** `.changeset/20274-agent-memory-contract.md`. - The levels are `@objectstack/spec` minor and `@objectstack/platform-objects` patch (for the catalog leaves). - It carries the BREAKING header, the FROM → TO table and the one-line remedy: "declare `maxEntries` and `reflectionInterval` when `longTerm.enabled`; delete `store`". - It declares `Clause-②: yes (narrowing)` and the ADR-0087 marker `registered agent-memory-long-term-store-removed, agent-memory-store-retired-and-limits-required`. The four surface ratchets (`api-surface`, `authorable-surface`, `json-schema.manifest`, `api-surface-signatures`) are byte-identical, as expected for a NESTED key of an inline block: it has no `authorable-surface/` line of its own. `spec-changes.json` and the upgrade guide are unchanged, because step 18 is not yet projected; `PROTOCOL_MAJOR` is 17, the same state as the structured-output precedent. ## Verification (at `39412feb9e`, after merging `origin/main` at `ca0dfb658a`) - `@objectstack/spec` build + `check:generated`: "All 15 generated artifacts are up to date". - `@objectstack/spec` `vitest --project local`: 599 files, 17583 passed, 1 todo. - `@objectstack/spec` `vitest --project repo`: 43 of 49 files, 705 passed. The other 6 are NOT MEASURED; see below. - `@objectstack/spec` `typecheck` (`tsc --noEmit`, the scripts program and the test layer): OK. "52 file(s) / 246 error(s)" is exactly the pinned debt. `tsc --listFiles` over `tsconfig.test.json` lists both `src/ai/agent.test.ts` and `src/ai/agent-memory-store-retirement.test.ts`, and none of the 246 errors is in either file. So the `@ts-expect-error` on `store` is live. - Consumers: - `@objectstack/lint` reads `liveness/agent.json`: `test` 119 files, 5575 passed; `typecheck` OK. - `@objectstack/platform-objects` holds the catalogs: `test` 59 files, 949 passed; `typecheck` OK. - `node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --ran`: "117 derived famil(ies) accounted for — 117 run, 0 NOT-MEASURED (a DERIVED zero — all 117 recorded an exit code and none of them is 3)". Each exit code was written to disk before any pipe. The list includes: - `check:adr-0087-registration`: "1 declared-breaking changeset(s), each carrying an ADR-0087 disposition … [BREAKING+bang+clause-②-narrowing] registered agent-memory-long-term-store-removed, agent-memory-store-retired-and-limits-required"; - `check-changeset-no-major`: "This diff introduces no `major` bump"; - `check:empty-changeset`, `check:liveness`, `check:doc-authoring`, `check:nul-bytes`, `check:migration-registry`, `check:cross-package-test-inputs`, `check:i18n`, `check:i18n-stale-fill` and `check:type-check-debt`, which re-measured in 116.6 s. - On first runs, before the build closures existed, a few gates exited 3 (PREREQUISITE NOT MET). All were re-run green after building the lint, client and CLI closures. - One `check:dts-closure` red was a race with this worktree's own concurrent spec rebuild. It then named three unrelated packages (`organizations`, `plugin-approvals`, `verify`) whose `dist` had no `.d.ts`. They were rebuilt, and it is green. - `check:i18n-coverage` and `check:i18n-walk-parity` also ran green. - **ESLint, as a proven narrowing** (the repo-wide `pnpm lint` belongs to CI): - The run covered the 13 touched `.ts` files with `--no-inline-config --format json`: 13 files linted, 0 errors, 0 warnings. - All 13 are inside the config's population: `ESLint.isPathIgnored` is false for each. - The narrowing cannot have excluded anything. `eslint.config.mjs` enables no type-aware linting (no `parserOptions.project`; its own comment at `:328` says so), so this diff cannot move the verdict on any untouched file. - **Ablation** (committed tree `8965af164d`; `scripts/ablation-replace.mjs`; each mutation proven on disk by anchor count and blob hash, and each restore proven by blob equal to HEAD and an empty `git diff HEAD`). Both test files import `./agent.zod` relatively, so no `dist` rebuild is involved. - **The contract check.** The anchor `const enabled = memory.longTerm?.enabled === true;` was replaced by an early return: 6 failed, 67 passed. The six are the five refusal pins and the D2 lit control. The two acceptance pins stayed green. - A first attempt, whose replacement contained its own anchor, was a no-op. The tool refused it (anchor count 1 → 1), so no test ran. - **The tombstone.** `store: retiredKey(…)` was replaced by the old three-value enum: 5 failed, 68 passed. The five are the every-value refusal, the did-you-mean pin, the tsc/parse pin, the `defineStack` envelope pin and the artifact boot-door pin. - The direction is red in both runs, as expected. **NOT MEASURED** - Six `@objectstack/spec` repo-project files: `publish-smoke-boot-failure`, `publish-smoke-port-collision`, `dist-freshness`, `dist-freshness-adoption`, `build-schemas-check-mode` and `schema-tree-freshness`. Reason: they drive whole builds and exercise build tooling this diff does not touch; the precedent PR saw them cap-killed at the foreground ceiling. They are declared to CI. - `@objectstack/cli` integration tier. Reason: declared to CI; no CLI file is touched. ## Fixture and producer census - **Producers.** Measured at merge base `6d487d2094`, outside `packages/spec`, in `examples/**` and `packages/**`: - `longTerm`: 0 non-test files and 0 test files. `reflectionInterval`: 0 and 0. - The lit control `guardrails` hits 4 non-test files, the four metadata-form catalogs. - So no producer exists in this repo. - Cloud's built-in agents also have none, per the ruling record's own census. Tenant-authored agents are NOT MEASURED. - **objectui**, at the dispatch pin `31971ff1e28f` and at the current pin `89cad75d55` (after PR #21380): - `longTerm`: 1 file, `packages/app-shell/src/views/metadata-admin/previews/AgentPreview.tsx`, a display-only preview that reads `memory.longTerm.store` through an `as any`. No build break follows. See Acceptance notes. - `reflectionInterval`: 0. The control `AgentSchema` hits 3 files. - **Fixtures that pinned the old acceptance, flipped:** - `packages/spec/src/ai/agent.test.ts` had two. "should accept agent with memory configuration" wrote `store: 'vector'` and expected it back; it now writes both numbers and asserts that no `store` materializes. "should accept all memory store backends" is replaced by acceptance of memory without enabled long-term memory. - `packages/lint/src/lint-liveness-properties.test.ts` had three cases using `agent.memory` as the live `experimental` ledger witness. They were repointed to `tool.outputSchema`: `memory` is no longer experimental, and `tool.outputSchema` is the remaining experimental row with no retirement queued. `agent.lifecycle` has one, the spec half tracked separately. - **New pins.** - `agent.test.ts` gains 8 contract cases. - The new `src/ai/agent-memory-store-retirement.test.ts`, registered in `vitest.repo-tests.json`, holds 14 cases: the tombstone at every door, the D2 conversion, the registration, and the tree-scoped absence walk. - The walk covers the five roots `@objectstack/spec#test:repo` already declares in `scripts/cross-package-test-inputs.mjs`. Its matcher judges a `longTerm` block that writes `store` / `backend` / `storage` / `provider`, has an anti-vacuity case, and excludes the conversions fixture, release notes and gitignored output. - **Other docs.** `content/docs/**` other than the regenerated reference page: 0 hits. ## Acceptance notes - **Published skill text that is now false (`skills/**`, Tier H, not edited here).** `skills/objectstack-ai/SKILL.md:311-313` says "`memory` is declared only — no runtime reads it". No `skills/**` text names `longTerm` or `store`. Carrier: the skills seat that took the `guardrails` half of the same sentence. - **objectui `AgentPreview.tsx:205-216`** renders `short.maxMessages` (retired by ADR-0013 D3) and `long.store` (retired here). Both now render nothing. It is display-only and read through `as any`, so the Console Pin Gate is unaffected. No carrier is named. - **The release number in the prescriptions.** They say "removed in @objectstack/spec 17.7.0", which assumes the next release is a minor (the label is 17.6.0, published). That is the same assumption the structured-output prescriptions make. - **`dropped-refinements.baseline.json` `measured.refinementSitesThatDidProject`** reads 369, while this tree's build prints 436. That counter was stale before this PR, and only `droppedRefinementSites` was moved (+5). No carrier is named. - **The liveness README's `agent` row** still says "autonomy tier experimental". After this flip, `lifecycle` is the only experimental agent row, and its retirement is queued. The precedent flips left the row as written, and so does this one. --- _Generated by [Claude Code](https://claude.ai/code/session_01YDt3PzwfrkuFzUBF89WPmM)_ --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent ceb4a93 commit 22c2d6f

19 files changed

Lines changed: 1066 additions & 56 deletions
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
---
2+
'@objectstack/spec': minor
3+
'@objectstack/platform-objects': patch
4+
---
5+
6+
feat(spec)!: an agent's `memory` contract states exactly what the runtime honours — `maxEntries` and `reflectionInterval` are required once long-term memory is enabled, `longTerm.store` is retired, and the block is `live`, enforced by the cloud AI runtime (#20274)
7+
8+
**BREAKING** — `agent.memory` narrows to what the cloud AI runtime, the one runtime
9+
that executes agents, actually does with it. That runtime recalls the newest
10+
`maxEntries` distilled notes for the user before the first round, writes one note
11+
every `reflectionInterval` delivered interactions, evicts notes beyond `maxEntries`,
12+
and keeps them in its own database store. Before an agent's first turn it refused
13+
exactly the declarations this spec still accepted, so authoring now refuses them,
14+
by name, with a prescription (ADR-0049 enforce-or-remove):
15+
16+
- **`longTerm.maxEntries` and `reflectionInterval` are required when
17+
`longTerm.enabled` is true.** No default is declared for either: none has a
18+
measured basis, and the runtime adds none.
19+
- **`reflectionInterval` is refused without an enabled `longTerm`** — a reflection
20+
writes a long-term note, so with none enabled it would do nothing.
21+
- **`longTerm.store` is retired as a whole key.** The memory store is platform
22+
infrastructure, not agent metadata: the runtime keeps the notes in its own
23+
database store, and refused `vector` (the key's default, so what an omitted
24+
`store` parsed to) and `redis`. Its old spellings `backend`, `storage` and
25+
`provider` under `longTerm` are answered with the same prescription instead of
26+
being steered onto `store`.
27+
28+
`longTerm.enabled` is unchanged.
29+
30+
### FROM → TO
31+
32+
| before | what to write instead |
33+
| --- | --- |
34+
| `memory.longTerm.store` — any value, `database` included | delete the key; where the notes are kept is the platform's choice. |
35+
| `longTerm: { enabled: true, … }` without `maxEntries` | add `maxEntries`: how many distilled notes are kept for each user (an integer of at least 1). |
36+
| `longTerm: { enabled: true, … }` without `memory.reflectionInterval` | add `reflectionInterval`: how many delivered interactions pass between the reflections that write a note (an integer of at least 1). |
37+
| `memory.reflectionInterval` without `longTerm.enabled: true` | enable long-term memory with both numbers, or delete `reflectionInterval`. |
38+
39+
**The one-line fix: declare `maxEntries` and `reflectionInterval` when `longTerm.enabled`; delete `store`.**
40+
`os migrate meta --from 17` lists the mechanical edits for existing sources (the
41+
`store` deletion); the two numbers are the author's to choose.
42+
43+
Each refusal is a parse error at the key's own path, naming the key and the fix, and
44+
`store` also fails `tsc` (its input type is `never`).
45+
46+
### The retirement kit
47+
48+
- **Tombstone.** `longTerm.store` is a `retiredKey()` carrying the prescription; the
49+
three old alias spellings moved from `aliases` to `guidance`, because an alias may
50+
not steer an author onto a tombstone.
51+
- **The contract check** is a refinement on `memory` (`reflectionInterval` is
52+
`longTerm`'s sibling), one `custom` issue per missing or misplaced key. A JSON
53+
Schema cannot state a value-conditioned requirement in the closed projection list,
54+
so the published `ai/Agent` schema (and the four installed-package schemas that
55+
embed agents) names the site in `x-dropped-refinements`, recorded in
56+
`dropped-refinements.baseline.json`.
57+
- **D2 conversion `agent-memory-long-term-store-removed`** (step 18, retired from the
58+
load path): it deletes `store` from `memory.longTerm`, whatever it holds — the
59+
delete is lossless, because no value of it ever chose a backend. Stored
60+
`sys_metadata` agent rows and built artifacts replay it; one notice per agent. It
61+
supplies neither number.
62+
- **D3 entry `agent-memory-store-retired-and-limits-required`** carries the judgement
63+
the conversion cannot make: the two numbers an enabled `longTerm` now requires.
64+
- **`RETIRED_KEYS_BY_MAJOR[18]`** registers `ai/Agent:memory.longTerm.store`.
65+
- **No deprecation window**, per the project's startup-stage posture.
66+
67+
### Describes and the liveness ledger
68+
69+
- `agent.memory` drops `[EXPERIMENTAL — not enforced]`: it states that the cloud AI
70+
runtime enforces it and that the open framework edition does not run agents.
71+
`longTerm`, `enabled`, `maxEntries` and `reflectionInterval` each state what the
72+
runtime does with them.
73+
- The ledger row moves `experimental` → `live`, citing the cloud reader
74+
`agent-runtime.ts#compileAgentMemory` (via `AgentRuntime.resolveTurnGuardrails`),
75+
the enforcement in `ai-service.ts` and the store `agent-memory.ts#AgentMemoryStore`,
76+
as attested by the cloud seat's reading at cloud `ef5a4344`, `verifiedAt`
77+
2026-10-02. `os lint` / `os validate` no longer warn
78+
`liveness-experimental-property` on an agent that sets `memory`.
79+
- ⚠️ **The window, stated.** At `ef5a4344` the cloud reader still reads `store`: it
80+
honours `database` only and refuses `vector` and `redis`. Cloud drops `store` in
81+
that one reader once this release reaches its pin, and no earlier.
82+
83+
### The agent form's help texts
84+
85+
- The `memory` row's help text on the agent metadata form named short-term memory,
86+
a key the schema refuses. It now states what memory does and that `maxEntries`
87+
and `reflectionInterval` are required once long-term memory is enabled.
88+
- The neighbouring `planning` row named a strategy and a replan switch the schema
89+
does not declare; it now states the one key it has, the iteration cap.
90+
- The `platform-objects` metadata-form catalogs follow: the English leaves are
91+
regenerated, and the `zh-CN`, `ja-JP` and `es-ES` leaves are authored, not copied.
92+
93+
⚠️ **The out-of-repo consumer population is NOT MEASURED.** `@objectstack/spec` is
94+
published, and tenant-authored agents were not measured. This repo authors no
95+
`longTerm` outside `packages/spec`, and no cloud built-in agent declares one.
96+
97+
Clause-②: yes (narrowing)
98+
99+
<!-- adr-0087: registered agent-memory-long-term-store-removed, agent-memory-store-retired-and-limits-required -->

‎content/docs/references/ai/agent.mdx‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ const result = AIModelConfigSchema.parse(data);
5858
| **access** | `string[]` | optional | Who can chat with this agent |
5959
| **permissions** | `string[]` | optional | Required permission-set capabilities |
6060
| **planning** | `{ maxIterations: integer }` | optional | Autonomous reasoning and planning configuration |
61-
| **memory** | `{ longTerm?: object; reflectionInterval?: integer }` | optional | [EXPERIMENTAL — not enforced] Agent memory management. Parsed but no runtime consumer yet. |
61+
| **memory** | `{ longTerm?: object; reflectionInterval?: integer }` | optional | Agent memory (long-term notes recalled before each conversation and written by periodic reflection), enforced by the cloud AI runtime; the open framework edition does not run agents. |
6262
| **guardrails** | `{ maxTokensPerInvocation?: integer; maxExecutionTimeSec?: integer; blockedTopics?: string[] }` | optional | Safety guardrails for the agent (token budget, time limit, blocked topics), enforced per user turn by the cloud AI runtime; the open framework edition does not run agents. |
6363
| **structuredOutput** | `{ format: Enum<'json_object' \| 'json_schema'>; schema?: Record<string, any>; strict: boolean; retryOnValidationFailure: boolean; … }` | optional | Structured output contract for the agent's final answer (JSON format, schema, retries, fallback format, transform steps), enforced on every final answer by the cloud AI runtime; the open framework edition does not run agents. |
6464
| **protection** | `{ lock: Enum<'none' \| 'no-overlay' \| 'no-delete' \| 'full'>; reason: string; docsUrl?: string }` | optional | Package author protection block — lock policy for this agent. |
@@ -101,8 +101,8 @@ const result = AIModelConfigSchema.parse(data);
101101

102102
| Property | Type | Required | Description |
103103
| :--- | :--- | :--- | :--- |
104-
| **longTerm** | `{ enabled: boolean; store: Enum<'vector' \| 'database' \| 'redis'>; maxEntries?: integer }` | optional | Long-term / persistent memory |
105-
| **reflectionInterval** | `integer` | optional | Reflect every N interactions to improve behavior |
104+
| **longTerm** | `{ enabled: boolean; maxEntries?: integer }` | optional | Long-term memory: distilled notes kept per user and agent and recalled before each conversation |
105+
| **reflectionInterval** | `integer` | optional | Reflect every N delivered interactions: each reflection writes one distilled note to long-term memory. Required when longTerm.enabled is true, and refused without it |
106106

107107
### Nested Shape: `Agent.guardrails`
108108

‎packages/lint/src/lint-liveness-properties.test.ts‎

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,13 @@ describe('lintLivenessProperties', () => {
119119
expect(ruleOf(findings, 'nodes.outputSchema')).toBe(LIVENESS_DEAD_PROPERTY);
120120
});
121121

122-
it('warns on an experimental prop with no authorWarn of its own (agent.memory)', () => {
122+
it('warns on an experimental prop with no authorWarn of its own (tool.outputSchema)', () => {
123123
// `experimental` warns implicitly — shouldWarn() treats a declared-but-
124124
// unenforced guarantee like an opted-in dead prop. Repointed from
125-
// action.undoable in #3714, which turned out to have two objectui readers.
126-
const findings = lintLivenessProperties({ agents: [{ name: 'ag1', memory: { kind: 'buffer' } }] });
127-
const f = findings.find((x) => x.message.includes('`memory`'));
125+
// action.undoable in #3714, which turned out to have two objectui readers,
126+
// and from agent.memory in #20274, which the cloud AI runtime enforces.
127+
const findings = lintLivenessProperties({ tools: [{ name: 't1', outputSchema: { type: 'object' } }] });
128+
const f = findings.find((x) => x.message.includes('`outputSchema`'));
128129
expect(f).toBeDefined();
129130
expect(f!.rule).toBe('liveness-experimental-property');
130131
});
@@ -930,12 +931,12 @@ describe('lintLivenessProperties', () => {
930931
describe('never throws on a malformed collection item (#11385)', () => {
931932
it('flat TYPE_COLLECTIONS loop: skips a null item and keeps walking past it', () => {
932933
const findings = lintLivenessProperties({
933-
// agent.memory is a real, currently-`experimental` ledger row (see
934+
// tool.outputSchema is a real, currently-`experimental` ledger row (see
934935
// "warns on an experimental prop" above) — a real ledger witness,
935936
// not a synthetic one.
936-
agents: [null, { name: 'ag1', memory: { kind: 'buffer' } }],
937+
tools: [null, { name: 't1', outputSchema: { type: 'object' } }],
937938
});
938-
expect(paths(findings).some((m) => m.includes('`memory`'))).toBe(true);
939+
expect(paths(findings).some((m) => m.includes('`outputSchema`'))).toBe(true);
939940
});
940941

941942
it('object walk: skips a null item and keeps walking past it', () => {
@@ -1596,12 +1597,12 @@ describe('a per-type ledger that could not be READ is reported once (#19276)', (
15961597
});
15971598

15981599
it('keeps walking the types whose ledgers ARE readable, and puts the fault first', () => {
1599-
// agent.memory is a real `experimental` row, so this proves the fault does
1600-
// not abort the pass: one type is dark, the rest still enforce, and the
1601-
// line that explains the darkness is the one a reader meets first.
1600+
// tool.outputSchema is a real `experimental` row, so this proves the fault
1601+
// does not abort the pass: one type is dark, the rest still enforce, and
1602+
// the line that explains the darkness is the one a reader meets first.
16021603
const findings = lintLivenessPropertiesFromLedgerDir(
16031604
ledgerDirWith((dir) => rmSync(join(dir, 'object.json'))),
1604-
{ agents: [{ name: 'ag1', memory: { kind: 'buffer' } }] },
1605+
{ tools: [{ name: 't1', outputSchema: { type: 'object' } }] },
16051606
);
16061607
expect(findings.map((f) => f.rule)).toEqual([LIVENESS_LEDGER_UNREADABLE, LIVENESS_EXPERIMENTAL_PROPERTY]);
16071608
expect(findings[0].where).toBe("liveness ledger 'object'");

‎packages/platform-objects/src/apps/translations/en.metadata-forms.generated.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,11 +2394,11 @@ export const enMetadataForms: NonNullable<TranslationData['metadataForms']> = {
23942394
},
23952395
planning: {
23962396
label: "Planning",
2397-
helpText: "Autonomous reasoning configuration (strategy, max iterations, replan)"
2397+
helpText: "Autonomous reasoning configuration: the maximum number of reasoning iterations before the agent stops (1–100, default 10)."
23982398
},
23992399
memory: {
24002400
label: "Memory",
2401-
helpText: "Memory management (short-term, long-term, reflection)"
2401+
helpText: "Long-term memory: distilled notes kept per user, recalled before each conversation and written by a reflection every reflectionInterval delivered interactions. When long-term memory is enabled, maxEntries and reflectionInterval are required. Enforced by the cloud AI runtime."
24022402
},
24032403
lifecycle: {
24042404
label: "Lifecycle",

‎packages/platform-objects/src/apps/translations/es-ES.metadata-forms.generated.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,11 +2394,11 @@ export const esESMetadataForms: NonNullable<TranslationData['metadataForms']> =
23942394
},
23952395
planning: {
23962396
label: "Planificación",
2397-
helpText: "Configuración de razonamiento autónomo (strategy, max iterations, replan)"
2397+
helpText: "Configuración de razonamiento autónomo: el número máximo de iteraciones de razonamiento antes de que el agente se detenga (1–100, 10 por defecto)."
23982398
},
23992399
memory: {
24002400
label: "Memoria",
2401-
helpText: "Gestión de memoria (short-term, long-term, reflection)"
2401+
helpText: "Memoria a largo plazo: notas destiladas que se guardan por usuario, se recuperan antes de cada conversación y las escribe una reflexión cada reflectionInterval interacciones entregadas. Cuando la memoria a largo plazo está habilitada, maxEntries y reflectionInterval son obligatorios. Lo aplica el runtime de IA en la nube."
24022402
},
24032403
lifecycle: {
24042404
label: "Ciclo de vida",

‎packages/platform-objects/src/apps/translations/ja-JP.metadata-forms.generated.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,11 +2394,11 @@ export const jaJPMetadataForms: NonNullable<TranslationData['metadataForms']> =
23942394
},
23952395
planning: {
23962396
label: "計画",
2397-
helpText: "自律推論設定(strategy, max iterations, replan)"
2397+
helpText: "自律推論設定: エージェントが停止するまでの最大推論反復回数(1〜100、既定値 10)。"
23982398
},
23992399
memory: {
24002400
label: "メモリ",
2401-
helpText: "メモリ管理(short-term, long-term, reflection)"
2401+
helpText: "長期メモリ: ユーザーごとに保持される要約ノート。各会話の前に呼び出され、配信済みのやり取り reflectionInterval 回ごとに 1 回のリフレクションで書き込まれます。長期メモリを有効にする場合、maxEntries と reflectionInterval は必須です。クラウド AI ランタイムが適用します。"
24022402
},
24032403
lifecycle: {
24042404
label: "ライフサイクル",

‎packages/platform-objects/src/apps/translations/zh-CN.metadata-forms.generated.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2394,11 +2394,11 @@ export const zhCNMetadataForms: NonNullable<TranslationData['metadataForms']> =
23942394
},
23952395
planning: {
23962396
label: "规划",
2397-
helpText: "自主推理配置(策略、最大迭代、是否重规划)"
2397+
helpText: "自主推理配置:代理停止前的最大推理迭代次数(1–100,默认 10)。"
23982398
},
23992399
memory: {
24002400
label: "记忆",
2401-
helpText: "记忆管理(短期、长期、反思)"
2401+
helpText: "长期记忆:按用户保存的提炼笔记,在每次会话前召回,并每隔 reflectionInterval 次已送达的交互由一次反思写入。启用长期记忆时,maxEntries 与 reflectionInterval 为必填。由云端 AI 运行时强制执行。"
24022402
},
24032403
lifecycle: {
24042404
label: "生命周期",

‎packages/spec/dropped-refinements.baseline.json‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,14 @@
33
"measured": {
44
"zod": "4.4.3",
55
"publishedSchemasWithDroppedRefinements": 215,
6-
"droppedRefinementSites": 635,
6+
"droppedRefinementSites": 640,
77
"refinementSitesThatDidProject": 369,
88
"refinementSitesWithNoJsonFormToCompare": 0
99
},
1010
"entries": {
1111
"ai/Agent": {
1212
"sites": [
13+
"memory",
1314
"structuredOutput.schema"
1415
]
1516
},
@@ -63,6 +64,7 @@
6364
"manifest.actions.element.in",
6465
"manifest.actions.element.in.ai.outputSchema",
6566
"manifest.actions.element.in.params.element.in",
67+
"manifest.agents.element.memory",
6668
"manifest.agents.element.structuredOutput.schema",
6769
"manifest.connectors.element.out",
6870
"manifest.dashboards.element.globalFilters.element",
@@ -168,6 +170,7 @@
168170
"data.options[1].manifest.actions.element.in",
169171
"data.options[1].manifest.actions.element.in.ai.outputSchema",
170172
"data.options[1].manifest.actions.element.in.params.element.in",
173+
"data.options[1].manifest.agents.element.memory",
171174
"data.options[1].manifest.agents.element.structuredOutput.schema",
172175
"data.options[1].manifest.connectors.element.out",
173176
"data.options[1].manifest.dashboards.element.globalFilters.element",
@@ -258,6 +261,7 @@
258261
"options[1].manifest.actions.element.in",
259262
"options[1].manifest.actions.element.in.ai.outputSchema",
260263
"options[1].manifest.actions.element.in.params.element.in",
264+
"options[1].manifest.agents.element.memory",
261265
"options[1].manifest.agents.element.structuredOutput.schema",
262266
"options[1].manifest.connectors.element.out",
263267
"options[1].manifest.dashboards.element.globalFilters.element",
@@ -308,6 +312,7 @@
308312
"data.packages.element.options[1].manifest.actions.element.in",
309313
"data.packages.element.options[1].manifest.actions.element.in.ai.outputSchema",
310314
"data.packages.element.options[1].manifest.actions.element.in.params.element.in",
315+
"data.packages.element.options[1].manifest.agents.element.memory",
311316
"data.packages.element.options[1].manifest.agents.element.structuredOutput.schema",
312317
"data.packages.element.options[1].manifest.connectors.element.out",
313318
"data.packages.element.options[1].manifest.dashboards.element.globalFilters.element",

0 commit comments

Comments
 (0)