Skip to content

fix(harness): populate retrievalConfig from memory strategy namespaces#1374

Open
padmak30 wants to merge 3 commits into
previewfrom
fix/ltm-harness
Open

fix(harness): populate retrievalConfig from memory strategy namespaces#1374
padmak30 wants to merge 3 commits into
previewfrom
fix/ltm-harness

Conversation

@padmak30
Copy link
Copy Markdown
Contributor

Description

Without retrievalConfig in the CreateHarness payload, the harness runtime had no instruction to retrieve from any namespace at inference time — so long-term memory was written correctly but never read back.

mapMemory now accepts the resolved Memory spec and derives retrievalConfig by collecting namespaces from all strategies.

computeHarnessHash now includes the Memory spec so that changes to strategy namespaces in agentcore.json trigger a redeploy even when harness.json is unchanged.

Related Issue

Closes # #1097

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update
  • Other (please describe):

Testing

How have you tested the change?

  • I ran npm run test:unit and npm run test:integ
  • I ran npm run typecheck
  • I ran npm run lint
  • If I modified src/assets/, I ran npm run test:update-snapshots and committed the updated snapshots

Checklist

  • I have read the CONTRIBUTING document
  • I have added any necessary tests that prove my fix is effective or my feature works
  • I have updated the documentation accordingly
  • I have added an appropriate example to the documentation to outline the feature, or no new docs are needed
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the
terms of your choice.

Without retrievalConfig in the CreateHarness payload, the harness runtime
had no instruction to retrieve from any namespace at inference time — so
long-term memory was written correctly but never read back.

mapMemory now accepts the resolved Memory spec and derives retrievalConfig
by collecting namespaces from all strategies.

computeHarnessHash now includes the Memory spec so that changes to strategy
namespaces in agentcore.json trigger a redeploy even when harness.json is
unchanged.
@padmak30 padmak30 requested a review from a team May 25, 2026 16:15
@github-actions github-actions Bot added the agentcore-harness-reviewing AgentCore Harness review in progress label May 25, 2026
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 25, 2026
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label May 25, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 25, 2026

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 43.6% 10129 / 23229
🔵 Statements 42.89% 10773 / 25117
🔵 Functions 40.45% 1708 / 4222
🔵 Branches 40.5% 6638 / 16388
Generated in workflow #3277 for commit ee91cc9 by the Vitest Coverage Report Action

Copy link
Copy Markdown

@agentcore-cli-automation agentcore-cli-automation left a comment

Choose a reason for hiding this comment

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

Thanks for tackling this! The core fix — populating retrievalConfig from the memory's strategy namespaces and including the memory spec in the harness config hash — is on the right track and matches what the runtime needs.

A couple of things to consider before merging:

  1. EPISODIC reflectionNamespaces are excluded from retrievalConfig. This may leave the issue partially unresolved for users with EPISODIC strategies (see inline comment).
  2. No test coverage for the redeploy-on-namespace-change behavior that the PR description calls out as a primary fix (see inline comment on harness-deployer.ts).

Minor: the memorySpec lookup in harness-deployer.ts only matches by memory.name, so harnesses that reference memory by arn won't get a retrievalConfig derived. This is probably acceptable as a known limitation (we can't introspect external memories), but worth confirming the intent.

Comment thread src/cli/operations/deploy/imperative/deployers/harness-mapper.ts Outdated
Comment thread src/cli/operations/deploy/imperative/deployers/harness-deployer.ts
@github-actions github-actions Bot removed the agentcore-harness-reviewing AgentCore Harness review in progress label May 25, 2026
buildRetrievalConfig now flattens reflectionNamespaces alongside namespaces
for EPISODIC strategies, so cross-session reflection summaries stored at the
parent namespace path are retrieved at inference time.

Also adds a unit test asserting that mutating strategies[*].namespaces in
agentcore.json produces a different configHash and triggers a harness update
rather than being silently skipped.
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 26, 2026
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label May 26, 2026

const deployedResources = deployedState.targets?.[targetName]?.resources;
const existingHarness = deployedHarnesses[entry.name];
const memorySpec = projectSpec.memories?.find(m => m.name === harnessSpec.memory?.name);
Copy link
Copy Markdown
Contributor

@tejaskash tejaskash May 26, 2026

Choose a reason for hiding this comment

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

Minor / low priority — flagging for awareness rather than as a blocker.

The spec lookup keys solely on harnessSpec.memory?.name. HarnessMemoryRefSchema (src/schema/schemas/primitives/harness.ts:188) makes both name and arn optional, and mapMemory already has an if (memory.arn) branch (harness-mapper.ts:280). For an arn-only ref, find(m => m.name === undefined) returns undefined and the harness ships without retrievalConfig.

That said, no CLI surface produces this shape — agentcore add harness always writes { name: ... }, and there's no --memory-arn flag. The only way to land here is hand-editing harness.json. So this is theoretical for any first-party flow.

Two reasonable resolutions:

  1. Tighten HarnessMemoryRefSchema to require name (drop the arn branch in mapMemory along with it), so the schema reflects what the tooling actually supports.
  2. Leave as-is and add a test asserting that the arn-only branch intentionally omits retrievalConfig, so a future contributor doesn't read it as a regression.

Either is fine — feel free to defer or close as out-of-scope.

jesseturner21 added a commit that referenced this pull request May 26, 2026
Includes EPISODIC reflectionNamespaces in the retrieval config so the
harness runtime searches all relevant memory namespaces at inference time.
Also incorporates memorySpec into the deploy hash so namespace changes
trigger a harness update.

Cherry-picked from #1374.
…refs

When a harness references memory by ARN only (no name field), the previous
lookup returned undefined, silently omitting retrievalConfig and excluding
the memory from the configHash. resolveMemorySpec now walks
deployedResources.memories to match by ARN and find the corresponding
projectSpec memory, so name-less refs that point at a CLI-managed memory
get the same treatment as name-based refs.

HarnessMemoryRef is exported from the schema barrel so it can be used as
the explicit parameter type on resolveMemorySpec.

Adds unit tests for both the ARN-match path and the intentional undefined
fallback for genuinely external memories.
@agentcore-devx-automation agentcore-devx-automation Bot added the claude-security-reviewing Claude Code /security-review in progress label May 26, 2026
@agentcore-devx-automation
Copy link
Copy Markdown
Contributor

Claude Security Review: no high-confidence findings. (run)

@agentcore-devx-automation agentcore-devx-automation Bot removed the claude-security-reviewing Claude Code /security-review in progress label May 26, 2026
jariy17 pushed a commit that referenced this pull request May 26, 2026
* feat: implement compile-time feature flag for preview/GA branch consolidation

Replace the dual-branch (main/preview) workflow with a single branch using
a compile-time __PREVIEW__ constant. esbuild's define block replaces the
constant at build time, enabling dead code elimination for GA builds while
keeping all harness/preview code in the same source tree.

Key changes:
- Add src/cli/feature-flags.ts with isPreviewEnabled() wrapper
- Configure esbuild define block and vitest define for __PREVIEW__
- Gate harness commands (add tool, remove tool/harness) behind isPreviewEnabled()
- Gate harness UI screens and create flow behind the flag
- Add globalThis shim in index.ts for tsx dev mode
- Update bundle.mjs to produce dual tarballs (GA + preview)
- Support ESBUILD_OUTFILE env var for isolated test builds
- Port all harness-related source files from preview branch
- Add preview-flag.test.ts verifying dead code elimination

* fix: remove unnecessary quotes around __PREVIEW__ key in esbuild config

Prettier requires unquoted object keys when valid identifiers.

* fix: skip harness integration and e2e tests in GA builds

Harness features are gated behind BUILD_PREVIEW=1 and eliminated from
GA bundles. Integration and e2e tests that exercise harness commands
must skip when running against the default (GA) build.

* fix: gate harness options in invoke/create commands and fix remove memory cleanup

- Wrap harness-related CLI options in invoke command behind isPreviewEnabled()
  so they don't leak into GA build's --help output
- Wrap harness-related CLI options in create command behind isPreviewEnabled()
- Fix remove harness leaving orphaned memory entries in agentcore.json
- Fix deploy preflight rejecting harness-only projects
- Add integration test for harness re-add after removal

* fix: auto-deploy harness in TUI dev mode before invoking

The TUI path for `agentcore dev` skipped deployment, going straight to
the invoke screen. This caused "No deployed targets found" errors for
users who hadn't manually run `agentcore deploy`. Now uses the existing
useDevDeploy hook to deploy before transitioning to harness invoke mode.

* fix: use queueMicrotask for deploy-to-harness transition in TUI dev

The derived effectiveMode approach didn't trigger re-renders, leaving the
deploy screen stuck after completion. Switch to queueMicrotask + setMode
(matching the preview branch pattern) so the transition fires correctly.
Also handles browser mode by calling onLaunchBrowser after deploy.

* fix: match preview branch deploy UI and persist deployHash

- Deploy screen in TUI dev mode now matches preview branch: shows
  "Deploying project resources..." with DeployStatus CFN messages,
  filters redundant step, yellow error text, and log path link.
- Persist deployHash in deployed-state.json after successful deploys
  so canSkipDeploy can detect unchanged projects and skip re-deploy.

* fix: align harness UX with preview branch

- InvokeScreen: Ctrl+N for new session (was bare N), hint messages
  rendered in gray, context-sensitive "Loading..."/"Thinking..." label,
  directional scroll arrows instead of numeric range
- DevScreen: disable keyboard input while exiting (!isExiting guard)
- deploy/actions: imperative harness teardown before stack destroy
  (gated behind isPreviewEnabled) so harnesses aren't orphaned
- browser-mode: resolve harness traces via resolveAgentOrHarness
  instead of ignoring harnessName parameter
- resolve-agent: add resolveHarness and resolveAgentOrHarness helpers

* fix: hint message render order and harness/runtime disambiguation

- isHint check now comes after isExec (matching preview branch) so
  exec messages always render as magenta, not gray
- When a project has both runtimes and harnesses and no flag is given,
  show a clear error listing both --runtime and --harness options

* fix: route harness invocations and show deploy box in dev mode

The browser in `agentcore dev` could not invoke harnesses because the
/invocations POST handler never checked for harnessName in the request
body. Add early routing to handleHarnessInvocation when present.

The deploy progress box was missing because useDevDeploy did not pass
verbose: true or onResourceEvent to handleDeploy, so the switchableIoHost
was never created and CloudFormation messages never reached the TUI.

Constraint: handleHarnessInvocation handler already existed but was unreachable
Rejected: Adding a separate /harness-invocations endpoint | breaks frontend contract
Confidence: high
Scope-risk: narrow

* fix: serve harness info in status API and fix deploy message flow

The browser frontend could not discover harnesses because /api/status
did not include harness data or selectedHarness in its response.

The deploy box was still not showing because switchableIoHost was only
created with verbose:true, but preview also creates it when
onDeployMessage is provided. Also wire onDeployMessage into the
setOnMessage callback so both callbacks receive deploy events.

Constraint: frontend polls /api/status to discover available targets
Rejected: Separate /api/harnesses endpoint | adds complexity for no benefit
Confidence: high
Scope-risk: narrow

* fix: include harnesses in /api/resources response for browser UI

The frontend Agent Inspector crashes with "Cannot read properties of
undefined (reading 'find')" when switching to a harness because the
/api/resources endpoint was missing the harnesses array entirely.

Constraint: Frontend expects harnesses array with deploymentStatus and deployed fields
Confidence: high
Scope-risk: narrow

* test: add unit tests for harness invocation and status handlers

Covers validation, routing, SSE streaming, error handling, and
the harness fields added to /api/status response.

Confidence: high
Scope-risk: narrow

* test: add unit tests for resolve-agent, change-detection, and harness-mapper

Cover the untested middle-layer logic that routes invocations, decides
whether deploys can be skipped, and maps harness specs to API payloads.

Confidence: high
Scope-risk: narrow

* fix: adjust preview-flag DCE test for keepNames compatibility

The keepNames:true esbuild option (added for better error stacks)
preserves class/function name strings even in dead code paths.
Adjust assertions to check for harness-only module markers that
are fully tree-shaken, rather than name strings that survive.

Confidence: high
Scope-risk: narrow

* fix: pass structured DeployMessage through to TUI instead of plain strings

The dev deploy hook was re-wrapping string messages into DeployMessage
objects with hardcoded values. Now the real message (with actual level,
code, timestamp) flows through directly from CDK.

* fix(harness): populate retrievalConfig from memory strategy namespaces

Includes EPISODIC reflectionNamespaces in the retrieval config so the
harness runtime searches all relevant memory namespaces at inference time.
Also incorporates memorySpec into the deploy hash so namespace changes
trigger a harness update.

Cherry-picked from #1374.

* fix: rewrite dev command to resolve merge conflict with telemetry refactor

The merge conflict resolution left duplicated code blocks and mismatched
braces. Rebuilt from main's withCommandRunTelemetry+recorder pattern and
re-applied preview feature flag gates (harness support, skip-deploy,
TUI picker).

* fix: address PR review feedback from jariy17

- Remove unnecessary `as unknown as` cast in agentcore-control.ts (SDK
  already has IndexedKey type)
- Optimize preview build to only re-run esbuild (not full tsc + assets)
- Delete dead code: poll.ts and its test (nothing imports it)
- Error when harness enters FAILED state after create/update instead of
  silently returning success
- Add unit tests for harness-deployer (create, update, skip, teardown,
  FAILED status, role resolution, retry, polling)

* fix: update release workflows for single-branch preview model

- release.yml: set BUILD_PREVIEW=1 for preview builds
- release-main-and-preview.yml: rewrite as single-PR flow using
  preview-version.json for the preview version track (no separate
  preview branch needed)
- Remove sync-preview.yml (no preview branch to sync)
- Update preview-version.json to match current npm state (1.0.0-preview.9)

Constraint: preview and GA are both built from main, differentiated by BUILD_PREVIEW env var at esbuild time
Confidence: high
Scope-risk: narrow

* feat: add release_target input to select main, preview, or both

Allows running the release workflow for just main-only, preview-only,
or both together. Jobs are conditionally skipped based on the selection.

Confidence: high
Scope-risk: narrow

* fix: use github.ref_name for release branch selection

Allows triggering the release workflow from any branch via the GitHub
UI branch selector, instead of hardcoding main.

Confidence: high
Scope-risk: narrow

* chore: remove unused BUILD_PREVIEW env from release.yml

Preview releases are handled by release-main-and-preview.yml.

Confidence: high
Scope-risk: narrow
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.

3 participants