Skip to content

fix(amp): correct merged connector follow-up - #483

Merged
wey-gu merged 6 commits into
nowledge-co:mainfrom
IceCodeNew:fix/amp-coderabbit-followup
Aug 9, 2026
Merged

fix(amp): correct merged connector follow-up#483
wey-gu merged 6 commits into
nowledge-co:mainfrom
IceCodeNew:fix/amp-coderabbit-followup

Conversation

@IceCodeNew

@IceCodeNew IceCodeNew commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Follow-up to merged PR #480. Fixes the Codex registry/test version contract, makes Amp installation recoverable, disposes bootstrap state, strengthens transcript fingerprints, serializes manual and automatic capture, prevents post-dispose rescheduling, and aligns static tests with the session.start bootstrap. Focused Amp tests: 187 passed, 100% coverage; Codex validator passes. The unrelated integrations/README changes from PR #482 are intentionally not included.

Summary by CodeRabbit

  • New Features

    • Context bundles now preload at session start and apply once per conversation thread.
    • Plugin installation supports configurable directory-based deployments with safer replacement handling.
  • Bug Fixes

    • Improved capture coordination to prevent duplicate, overlapping, or post-disposal operations.
    • Message change detection now recognizes payload changes even when content length is unchanged.
    • Append fallback behavior is limited to conflict responses.
    • Bootstrap and installation failures preserve existing functionality where possible.
    • Independent conversations now receive their own context bundles.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd0ccbaa-acfb-414d-9d51-16b9eced3a10

📥 Commits

Reviewing files that changed from the base of the PR and between f5572aa and 0f31824.

📒 Files selected for processing (2)
  • nowledge-mem-amp-plugin/scripts/install.sh
  • tests/plugin_e2e/test_key_plugins_e2e.py
🚧 Files skipped from review as they are similar to previous changes (2)
  • tests/plugin_e2e/test_key_plugins_e2e.py
  • nowledge-mem-amp-plugin/scripts/install.sh

📝 Walkthrough

Walkthrough

The Amp plugin now installs as a staged directory, preloads Context Bundles per session, consumes them once per thread, coordinates manual and automatic captures, improves message signatures, and updates integration tests and coverage settings.

Changes

Amp plugin lifecycle

Layer / File(s) Summary
Unified staged installation
nowledge-mem-amp-plugin/scripts/install.sh, tests/plugin_e2e/test_key_plugins_e2e.py
The installer stages one plugin directory and its skill, validates both entrypoints, backs up existing files, and restores them when replacement fails. Contract tests verify the staged installation flow.
Session bootstrap lifecycle
nowledge-mem-amp-plugin/src/bootstrap.ts, nowledge-mem-amp-plugin/src/index.ts, nowledge-mem-amp-plugin/tests/bootstrap.test.ts, nowledge-mem-amp-plugin/tests/index.test.ts, tests/plugin_e2e/test_key_plugins_e2e.py
BootstrapManager preloads Context Bundles during session.start, injects each bundle once during agent.start, handles fail-open cases, and clears cached state during disposal.
Capture coordination and signatures
nowledge-mem-amp-plugin/src/sync.ts, nowledge-mem-amp-plugin/src/messages.ts, nowledge-mem-amp-plugin/tests/sync.test.ts, nowledge-mem-amp-plugin/tests/messages.test.ts
Manual captures serialize, automatic captures coalesce, disposed managers reject new work, conflict-only append fallback is enforced, and message payloads now affect capture signatures.
Integration test transport and coverage
nowledge-mem-amp-plugin/tests/e2e.test.ts, nowledge-mem-amp-plugin/vitest.config.ts
The E2E test uses configurable direct JSON requests with optional authentication. Coverage excludes src/index.ts and src/types.ts.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Amp
  participant BootstrapManager
  participant ContextBundleCLI
  Amp->>BootstrapManager: session.start(threadId)
  BootstrapManager->>ContextBundleCLI: preload Context Bundle
  ContextBundleCLI-->>BootstrapManager: bundle result
  Amp->>BootstrapManager: agent.start(threadId)
  BootstrapManager-->>Amp: consume bootstrap message once
Loading

Possibly related PRs

  • nowledge-co/community#479: Adds related session and subagent startup context preloading with controlled one-time Context Bundle consumption.
  • nowledge-co/community#480: Introduces the Amp plugin that this PR extends across installation, bootstrap, synchronization, and tests.
  • nowledge-co/community#482: Directly overlaps the Amp plugin bootstrap, installer, synchronization, message-signature, and index changes.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 45.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title identifies an Amp fix and accurately describes this pull request as a follow-up to the merged connector changes.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai 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.

Actionable comments posted: 5

🧹 Nitpick comments (3)
nowledge-mem-amp-plugin/tests/bootstrap.test.ts (1)

37-78: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the CLI argv and cover consume without preload.

The suite verifies call counts but never the arguments passed to nmem. A regression in the ["context", "--source-app", sourceApp] argv would pass. Add that assertion.

Also add a case where consume runs for a thread that never received preload. That path currently marks the thread consumed and returns {}, which is the behavior discussed in the src/bootstrap.ts comment on consume.

🧪 Proposed test additions
   it("does not refetch the same thread and manages sessions independently", async () => {
     const nmem = vi.fn(fakeNmem('{"ok":true}'))
     const manager = new BootstrapManager({ nmem }, { sourceApp: "amp", enabled: true })
     manager.preload("T-1")
     manager.preload("T-1")
     manager.preload("T-2")
     await manager.consume("T-1")
     await manager.consume("T-2")
     expect(nmem).toHaveBeenCalledTimes(2)
+    expect(nmem).toHaveBeenCalledWith(["context", "--source-app", "amp"])
   })
+
+  it("returns an empty result when the session was never preloaded", async () => {
+    const nmem = vi.fn(fakeNmem('{"ok":true}'))
+    const manager = new BootstrapManager({ nmem }, { sourceApp: "amp", enabled: true })
+    expect(await manager.consume("T-9")).toEqual({})
+    expect(nmem).not.toHaveBeenCalled()
+  })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nowledge-mem-amp-plugin/tests/bootstrap.test.ts` around lines 37 - 78, Update
the BootstrapManager tests to assert that nmem is called with ["context",
"--source-app", "amp"] in the preload/consume flow. Add a test covering
consume("T-1") without a prior preload, asserting it returns {} and preserves
the expected consumed-thread behavior described by consume.
nowledge-mem-amp-plugin/src/bootstrap.ts (1)

173-190: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Add a disposed guard so preload cannot start work after disposal.

dispose clears the map but does not block later calls. If session.start is delivered after amp.onDispose runs, preload recreates the session state and spawns a new nmem CLI process. The PR objectives state that the sync path prevents post-dispose rescheduling, so this manager should match that guarantee.

♻️ Proposed refactor
+  private disposed = false
+
   public preload(threadId: string): void {
-    if (!this.options.enabled) return
+    if (!this.options.enabled || this.disposed) return
   public dispose(): void {
+    this.disposed = true
     this.sessions.clear()
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nowledge-mem-amp-plugin/src/bootstrap.ts` around lines 173 - 190, Update the
session manager’s dispose/preload flow to track disposal explicitly and make
preload return without creating state or starting work after dispose() has run.
Ensure dispose() marks the manager disposed before clearing sessions, and have
preload check that guard while preserving normal behavior before disposal.
nowledge-mem-amp-plugin/tests/index.test.ts (1)

129-129: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Assert the disposal message, not any log call.

ampKnowledgeMem also logs the connector-loaded message during registration. amp.logger.log is therefore already called before the disposer runs, so this assertion passes even if the disposal log is deleted. Match the disposal text instead.

🧪 Proposed change
-    expect(amp.logger.log).toHaveBeenCalledWith(expect.stringContaining("disposed"))
+    expect(amp.logger.log).toHaveBeenCalledWith(expect.stringContaining("connector disposed"))

Replace line 129 with the assertion above.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@nowledge-mem-amp-plugin/tests/index.test.ts` at line 129, Update the disposer
test for ampKnowledgeMem to assert that amp.logger.log was called with the
specific disposal message, rather than merely checking that logging occurred.
Preserve the existing registration assertions and match the exact text emitted
by the disposer.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@nowledge-mem-amp-plugin/scripts/install.sh`:
- Around line 52-64: Update install_staged so the existing SKILL_DEST is moved
to BACKUP_SKILL only when STAGED_SKILL exists and will replace it. Preserve the
current skill untouched when no staged skill is present, while retaining backup
cleanup and restore behavior for actual skill replacements.
- Around line 25-36: Update the staging setup around STAGING_DIR so it is
created under PLUGINS_DIR rather than the system temporary directory, ensuring
plugin moves remain same-filesystem renames. Because SKILL_DEST is under
SKILLS_DIR, create and track a separate staging directory under SKILLS_DIR when
those directories may use different filesystems, and ensure cleanup removes both
staging directories.

In `@nowledge-mem-amp-plugin/src/bootstrap.ts`:
- Around line 155-165: Update consume so state.consumed is set only after
state.preloadedMessage is confirmed present and immediately before returning the
injected message. Leave the flag unchanged when no message exists, allowing a
later preload for the same thread to be consumed, and release the cached bundle
text from the thread state after returning it.

In `@nowledge-mem-amp-plugin/src/sync.ts`:
- Around line 157-164: Recheck the disposed state after awaiting the existing
state.inFlight capture in the manual-save flow, and return the disposed result
immediately when teardown occurred during the wait. Only clear the in-flight
state and call captureThread with force: true when the instance remains active.
- Around line 157-163: Update the in-flight cleanup loop in syncNow to set
state.inFlight to undefined only when it still references the captured previous
promise, then re-evaluate the loop against any newer guard. Add coverage for
three concurrent syncNow calls to verify captures remain serialized without
clearing a newer in-flight state.

---

Nitpick comments:
In `@nowledge-mem-amp-plugin/src/bootstrap.ts`:
- Around line 173-190: Update the session manager’s dispose/preload flow to
track disposal explicitly and make preload return without creating state or
starting work after dispose() has run. Ensure dispose() marks the manager
disposed before clearing sessions, and have preload check that guard while
preserving normal behavior before disposal.

In `@nowledge-mem-amp-plugin/tests/bootstrap.test.ts`:
- Around line 37-78: Update the BootstrapManager tests to assert that nmem is
called with ["context", "--source-app", "amp"] in the preload/consume flow. Add
a test covering consume("T-1") without a prior preload, asserting it returns {}
and preserves the expected consumed-thread behavior described by consume.

In `@nowledge-mem-amp-plugin/tests/index.test.ts`:
- Line 129: Update the disposer test for ampKnowledgeMem to assert that
amp.logger.log was called with the specific disposal message, rather than merely
checking that logging occurred. Preserve the existing registration assertions
and match the exact text emitted by the disposer.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 1926f20c-d1b0-4583-baad-2fbc765f1ad9

📥 Commits

Reviewing files that changed from the base of the PR and between de31be3 and dce352d.

📒 Files selected for processing (12)
  • nowledge-mem-amp-plugin/scripts/install.sh
  • nowledge-mem-amp-plugin/src/bootstrap.ts
  • nowledge-mem-amp-plugin/src/index.ts
  • nowledge-mem-amp-plugin/src/messages.ts
  • nowledge-mem-amp-plugin/src/sync.ts
  • nowledge-mem-amp-plugin/tests/bootstrap.test.ts
  • nowledge-mem-amp-plugin/tests/e2e.test.ts
  • nowledge-mem-amp-plugin/tests/index.test.ts
  • nowledge-mem-amp-plugin/tests/messages.test.ts
  • nowledge-mem-amp-plugin/tests/sync.test.ts
  • nowledge-mem-amp-plugin/vitest.config.ts
  • tests/plugin_e2e/test_key_plugins_e2e.py

Comment thread nowledge-mem-amp-plugin/scripts/install.sh
Comment thread nowledge-mem-amp-plugin/scripts/install.sh Outdated
Comment thread nowledge-mem-amp-plugin/src/bootstrap.ts
Comment thread nowledge-mem-amp-plugin/src/sync.ts Outdated
Comment thread nowledge-mem-amp-plugin/src/sync.ts Outdated

@coderabbitai coderabbitai 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.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@nowledge-mem-amp-plugin/src/sync.ts`:
- Around line 160-172: Add an early this.disposed check at the start of the then
callback in the run chain, before waiting on priorManual, returning
skipped("disposed", this.stableThreadId(threadId)) to prevent a forced capture
after teardown. Extend the manual-capture tests to queue two captures, dispose
while the first is pending, resolve it, and assert the second returns disposed
with only one write.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 9b9f0012-af83-4b3d-9a64-e58dc6265017

📥 Commits

Reviewing files that changed from the base of the PR and between dce352d and c5c93fa.

📒 Files selected for processing (4)
  • nowledge-mem-amp-plugin/scripts/install.sh
  • nowledge-mem-amp-plugin/src/bootstrap.ts
  • nowledge-mem-amp-plugin/src/sync.ts
  • nowledge-mem-amp-plugin/tests/sync.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • nowledge-mem-amp-plugin/scripts/install.sh

Comment thread nowledge-mem-amp-plugin/src/sync.ts
@IceCodeNew

Copy link
Copy Markdown
Contributor Author

Applied the latest review fixes and pushed commit f5572aa4. The installer now stages on the destination filesystem and preserves an existing skill when no replacement is shipped. Bootstrap consume no longer burns the one-shot state without a message. Manual capture queues are serialized, disposal is rechecked after waits, and the remaining defensive identity branch is documented/covered. All 6 CodeRabbit threads are now resolved. Validation: 189 unit tests passed, 100% coverage, strict TypeScript passed, Codex validator passed, and Ubuntu/Windows CI passed.

@wey-gu

wey-gu commented Aug 9, 2026

Copy link
Copy Markdown
Member

Thanks @IceCodeNew, this follow-up is very helpful. I did one small maintainer-side pass to keep the Amp installer fail-closed when the skill payload is missing, and re-ran the Amp unit/type/static checks plus the GitHub checks. Everything is green now, merging this in.

@wey-gu
wey-gu merged commit 0c7ee11 into nowledge-co:main Aug 9, 2026
3 checks passed
@IceCodeNew
IceCodeNew deleted the fix/amp-coderabbit-followup branch August 9, 2026 10:57
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.

2 participants