Skip to content

fix(sdk): pin memory in STEP_COMMON_FIELDS — main's suite is red - #223

Merged
kjgbot merged 1 commit into
mainfrom
fix/verb-field-lint-memory
Sep 7, 2026
Merged

fix(sdk): pin memory in STEP_COMMON_FIELDS — main's suite is red#223
kjgbot merged 1 commit into
mainfrom
fix/verb-field-lint-memory

Conversation

@kjgbot

@kjgbot kjgbot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

main is red. Run 34098150100 on 6394a2e9:

FAIL tests/verb-field-lint.test.ts > closed per-verb step fields
  > pins the per-verb descriptor and generates every foreign-field pair from it
AssertionError: expected [ 'id', 'type', 'dependsOn', …(3) ]
                to deeply equal [ 'id', 'type', 'dependsOn', …(2) ]

#221 added memory to STEP_COMMON_FIELDS (packages/sdk/src/step-fields.ts:25) without updating the pin in the test that guards that list.

The pin is an acknowledgement gate, not a duplicate of the source — its own comment says it exists so the change "cannot be silently undone". Adding memory to it is the acknowledgement, with a note on why the field is common rather than verb-specific: any step kind may declare a pack, so it generates no foreign-field pairs. The gate still fires if the descriptor moves again without a matching edit.

Verified

vitest tests/verb-field-lint.test.ts    78 passed
full SDK suite                          684 passed, 3 skipped, 0 failed

Worth noting separately

#221's own branch CI was already failing this — run 34097610746 on feat/step-memory-220, 6 minutes before the merge — and it merged anyway, carrying the red onto main. That is the second time in this session an auto-merge has acted while the gate was not satisfied; the first was #215 merging with defects a lens had named, tracked as #218. Whatever is deciding to merge is not reading linux-x64-artifact.

I would treat that as the more important finding than this one-line fix.

Refs #221, #218

…gain

main is red. #221 added `memory` to STEP_COMMON_FIELDS
(packages/sdk/src/step-fields.ts:25) without updating the pin that guards it:

    FAIL tests/verb-field-lint.test.ts > closed per-verb step fields
      > pins the per-verb descriptor and generates every foreign-field pair from it
    AssertionError: expected [ 'id', 'type', 'dependsOn', …(3) ]
                    to deeply equal [ 'id', 'type', 'dependsOn', …(2) ]

(run 34098150100, main @ 6394a2e.)

The pin exists so a change to the closed vocabulary "cannot be silently
undone" — it is an acknowledgement gate, not a duplicate of the source. Adding
`memory` to it is the acknowledgement, and the comment records why the field is
common rather than verb-specific: any step kind may declare a pack, so it
generates no foreign-field pairs.

This restores the gate rather than weakening it: the test still fails if the
descriptor changes again without a matching edit here.

Verified locally:
  vitest tests/verb-field-lint.test.ts   78 passed
  full SDK suite                         684 passed, 3 skipped, 0 failed

The branch CI for #221 was already failing this before it merged
(run 34097610746 on feat/step-memory-220); the merge carried the red onto main.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtQSAcGDta5VH9xiZFT4sR
@coderabbitai

coderabbitai Bot commented Sep 7, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Team

Run ID: 8afb4700-ffac-44db-9387-498dbbb7dadc


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

kjgbot pushed a commit that referenced this pull request Sep 7, 2026
…ed again

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtQSAcGDta5VH9xiZFT4sR

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No issues found across 1 file

Re-trigger cubic

@kjgbot

kjgbot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

maintainability lens — PASS

Maintainability review — PR #223

Context

Fix commit unblocks main: #221 added memory to STEP_COMMON_FIELDS
(packages/sdk/src/step-fields.ts:25) without updating the pin at
packages/sdk/tests/verb-field-lint.test.ts:176-182 that acknowledges any
change to the closed authoring vocabulary. This PR adds the missing entry and
a three-line comment explaining why memory is a common field rather than a
verb-specific one.

Findings

Notes (non-blocking):

  • packages/sdk/tests/verb-field-lint.test.ts:182-185 — the comment leads
    with Added by #221 (gate 5 slice 1). In six months that phrasing reads
    cold: #221 costs a GitHub round-trip and gate 5 slice 1 is internal
    project vocabulary that fades. The load-bearing second sentence — "any step
    kind may declare a pack, so it generates no foreign-field pairs" — stands on
    its own and explains the invariant the reader actually needs. git blame
    can supply the ticket. Consider trimming the first sentence.

Concern (worth a follow-up, not this PR):

  • packages/sdk/tests/verb-field-lint.test.ts:335-405 — the golden-ladder
    test is titled "preserves a valid v0.1.0 ladder with every declared per-verb
    field"
    and constructs one step per verb with every field in
    STEP_FIELDS_BY_TYPE. memory is now a declared common field, but none of
    the three steps in the ladder set it. That means the compile/compileYaml/
    preflight/flows check matrix that this file gates does not currently
    exercise memory at all — coverage lives only in
    packages/sdk/tests/memory.test.ts:8-14, which touches compileSpec on a
    deterministic step. A regression that dropped memory from the compileYaml
    or preflight paths, or from llm/agent verbs, would not turn this suite
    red. The pin advertises stronger coverage than it delivers now that a
    common field has been added without a corresponding golden-ladder update.
    This PR is scoped to unblock main; flagging as a follow-up.

Positives:

  • The comment records why memory yields no foreign-field pairs — this is
    the exact invariant that foreignFieldValue
    (packages/sdk/tests/verb-field-lint.test.ts:92-97) enforces, so a future
    author who moves memory to a verb-specific slot will fail loudly rather
    than silently.
  • The commit message pastes the assertion failure, cites the failing run id,
    and reports the verification counts — matches AGENTS.md §"Evidence is
    captured, not narrated."
  • The fix restores the acknowledgement gate rather than replacing it with a
    looser check; the test still fails if STEP_COMMON_FIELDS changes again
    without touching this pin.

No blockers. Two low-cost improvements suggested (comment trim, add memory
to the golden ladder in a follow-up).

REVIEW_PASSED

@kjgbot

kjgbot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

history lens — PASS

Blockers: none. PR #223 introduces no blocker under the three HISTORY criteria.

At packages/sdk/tests/verb-field-lint.test.ts, new lines 182–185 acknowledge memory in the expected common-field list. Commit 6394a2e (#221) already added that field to the production descriptor. This does not reintroduce the earlier mistake fixed by 512723c (#138): timeoutMs remains deterministic-only, and the explicit descriptor equality and foreign-field cases remain intact. I found no previously removed behavior recorded in ops/DRIVE-LOG.md that these additions restore.

The same lines introduce no new contradiction with RFC-0001. Gate 5 explicitly describes step-declared memory:; decision 10 governs its accounting. This patch changes neither accounting nor execution. It also leaves decision 13’s closed verb vocabulary intact. Updating this expected value introduces no mechanism allowing an executing agent to edit its judging gates.

Concern — evidence completeness, nonblocking: commit 84f69b2 reports “78 passed” and “684 passed, 3 skipped,” but supplies summaries rather than literal successful-run output and a reproducible full-suite command. Captured evidence would improve the record under AGENTS.md. I did not rerun those suites, and missing evidence alone does not establish that the claims are false.

Notes: the commit’s stated file scope matches the diff. Literal command:

git show --format= --stat 84f69b2

Captured output:

 packages/sdk/tests/verb-field-lint.test.ts | 4 ++++
 1 file changed, 4 insertions(+)

ops/NEXT.md’s separate crash-resume work package is not a correctness blocker for this patch. ops/DIRECTIVES.md contains no active directive.

REVIEW_PASSED

@kjgbot

kjgbot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

structure lens — PASS

$ git log --oneline -5; echo "---"; git branch --show-current
6394a2e feat(memory): journal step-declared packs with exact resume accounting (#221)
e649ad4 refactor(kernel): address durable channel maintainability review (#216)
b5896a8 feat(kernel): durable channels with acknowledged delivery and crash replay (#215)
5c9758b fix(workflows): drive sync guard still required the pre-#205 sdk/ path (#211)
de43f9e chore(release): v2.0.1

flow/lead-0902-reconcile

→ Read packages/sdk/tests/verb-field-lint.test.ts
→ Read packages/sdk/src/step-fields.ts

$ git log --oneline -1 -- packages/sdk/src/step-fields.ts; echo "---grep memory---"; grep -rn "memory" packages/sdk/src/step-fields.ts packages/sdk/src/spec.ts 2>/dev/null | head -50
6394a2e feat(memory): journal step-declared packs with exact resume accounting (#221)
---grep memory---
packages/sdk/src/step-fields.ts:25: 'memory',
packages/sdk/src/spec.ts:112: memory?: MemorySpec;
packages/sdk/src/spec.ts:289: memory?: KernelMemorySpec;

→ Read packages/sdk/src/spec.ts [offset=90, limit=220]

$ grep -rn "memory" packages/kernel packages/sdk/src --include="*.ts" | grep -iv "test" | head -60
packages/sdk/src/step-fields.ts:25: 'memory',
packages/sdk/src/compile.ts:112: ...(step.memory !== undefined ? { memory: step.memory } : {}),
packages/sdk/src/compile.ts:356: 'id', 'type', 'depends_on', 'max_iterations', 'retry', 'verification', 'memory',
packages/sdk/src/compile.ts:362: const commonKeys = ['id', 'type', 'depends_on', 'max_iterations', 'retry', 'verification', 'memory'] as const;
packages/sdk/src/compile.ts:381: ...(step['memory'] !== undefined ? { memory: kernelMemoryToAuthoring(step['memory'], ${at}.memory) } : {}),
packages/sdk/src/compile.ts:440: const memory = requireKernelObject(value, ['scope', 'query', 'budget'], at);
packages/sdk/src/compile.ts:442: scope: memory['scope'], query: memory['query'],
packages/sdk/src/compile.ts:443: budget: kernelBudgetToAuthoring(memory['budget'], ${at}.budget),
packages/sdk/src/compile.ts:510: ...(step.memory !== undefined ? { memory: {
packages/sdk/src/compile.ts:511: scope: step.memory.scope,
packages/sdk/src/compile.ts:512: query: step.memory.query,
packages/sdk/src/compile.ts:514: ...(step.memory.budget.maxTokensIn !== undefined ? { max_tokens_in: step.memory.budget.maxTokensIn } : {}),
packages/sdk/src/compile.ts:515: ...(step.memory.budget.maxTokensOut !== undefined ? { max_tokens_out: step.memory.budget.maxTokensOut } : {}),
packages/sdk/src/compile.ts:516: ...(step.memory.budget.maxDollars !== undefined ? { max_dollars: step.memory.budget.maxDollars } : {}),
packages/sdk/src/validate.ts:331: if (st['memory'] !== undefined) this.validateMemory(st['memory'], ${at}.memory);
packages/sdk/src/cli/tick-runner.ts:18: * not backfill from the epoch. But it means an in-memory-only cursor makes a
packages/sdk/src/spec.ts:112: memory?: MemorySpec;
packages/sdk/src/spec.ts:289: memory?: KernelMemorySpec;
packages/sdk/src/protocol.ts:176: memory?: MemoryInjectedPayload;
packages/sdk/src/worker.ts:94: ? await runAgentCli(spec.cli, memoryInstruction(spec.instruction, dispatch.memory), dispatch.wake_context, spec.model)
packages/sdk/src/worker.ts:153:function memoryInstruction(instruction: string, memory: StepDispatchEvent['memory']): string {
packages/sdk/src/worker.ts:154: return memory === undefined ? instruction
packages/sdk/src/worker.ts:155: : ${instruction}\n\nMemory context (journaled):\n${JSON.stringify(memory.pack)};

Structure lens review — PR #223 (verb-field-lint.test.ts only).

What changed

A single hunks adds 'memory' to the pinned STEP_COMMON_FIELDS expectation, plus a comment (verb-field-lint.test.ts:179-186). No source, no kernel, no spec, no compiler changes.

Assessment

Not blockers, but structural notes worth recording:

  1. The pin discipline slipped in feat(memory): journal step-declared packs with exact resume accounting #221, and fix(sdk): pin memory in STEP_COMMON_FIELDS — main's suite is red #223 is the repair. The test exists precisely to make any drifting of the per-verb descriptor fail loudly ("the per-verb descriptor is the only allowlist... nothing but this test says so," verb-field-lint.test.ts:407-414). Yet step-fields.ts:25 shipped 'memory' in feat(memory): journal step-declared packs with exact resume accounting #221 without updating this pin, so the descriptor and its own gate diverged across a merge. This PR restores the invariant. The fix is correct; the fact a fix was needed is a signal the "fail closed on the descriptor" loop is relied on but was not itself gating that merge.

  2. The comment is accurate. memory is on BaseStepSpec (spec.ts:110-112) and KernelStepCommon (spec.ts:288-295), so it is genuinely common, not verb-specific. It therefore never enters STEP_FIELDS_BY_TYPE, never produces a foreign-field label in CROSS_VERB_STEP_FIELDS, and correctly needs no VERB_FIELD_VALUES sample (verb-field-lint.test.ts:70-97). The claim "generates no foreign-field pairs" reproduces.

  3. Boundary shape is sound. memory compiles authoring→kernel at the journal boundary (compile.ts:510-516) and is declared, not silently stripped (compile.ts:112, 440-443), matching the kernel-small/pure rule. No product logic, no new primitive in the kernel; it's a declared pack with scope/query/budget.

  4. Mild smell, outside this diff's scope. MemorySpec.scope: 'script' | 'agent' (spec.ts:99) re-encodes verb-kind as a value discriminator on a common field. Structurally it's cleaner to keep the field common and the scope declarative than to fork it per-verb, so the current shape is defensible — but it's the kind of thing a future author may reach around. Non-blocking note.

No file growth, no coupling regression, no kernel contamination. The change is a faithful, narrow pin alignment with an honest comment.

REVIEW_PASSED

@kjgbot

kjgbot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

🎯 review-swarm: PASSED (M:pass H:pass S:pass)

Lens transcripts posted as sibling comments above.

@kjgbot

kjgbot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor Author

Independent 3-lens gate, run against origin/main..HEAD:

PRESWARM_structure:       REVIEW_PASSED
PRESWARM_history:         REVIEW_PASSED
PRESWARM_maintainability: REVIEW_PASSED

linux-x64-artifact — the job that runs cargo test --workspace and the SDK suite — is SUCCESS. The red review check is the empty CLOUD_API_KEY that fails on every PR in this repo (#218 territory), not anything about this change.

The maintainability lens made a point worth keeping: foreignFieldValue's fail-closed contract still holds here, because memory is common and so CROSS_VERB_STEP_FIELDS never asks for a sample value — and if anyone later moves memory into STEP_FIELDS_BY_TYPE, the generator throws with a clear message rather than silently generating nothing. The gate this PR restores is genuinely still a gate.

Merging: main has been red since 07:58Z and this is the fix.

@kjgbot
kjgbot merged commit 460c0f7 into main Sep 7, 2026
4 of 5 checks passed
@kjgbot
kjgbot deleted the fix/verb-field-lint-memory branch September 7, 2026 09:27
kjgbot pushed a commit that referenced this pull request Sep 7, 2026
…sion at 15G

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FtQSAcGDta5VH9xiZFT4sR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant