Skip to content

MS Teams: add channel archive persistence and deleted-channel cleanup#43190

Open
hddevteam wants to merge 8 commits intoopenclaw:mainfrom
hddevteam:feat/msteams-channel-archive
Open

MS Teams: add channel archive persistence and deleted-channel cleanup#43190
hddevteam wants to merge 8 commits intoopenclaw:mainfrom
hddevteam:feat/msteams-channel-archive

Conversation

@hddevteam
Copy link
Copy Markdown

Summary

  • add a new extensions/msteams-channel-archive plugin for persistent Teams channel archiving
  • persist channel messages plus archived attachments, and expose archive query tools
  • add deleted-channel cleanup, including a channel_deleted plugin hook driven by Teams conversationUpdate/channelDeleted

What changed

  • added the new msteams-channel-archive extension with durable JSONL archive storage and attachment copying
  • enriched inbound hook metadata so the archive plugin receives Teams-specific conversation, reply, media, and provider metadata
  • added plugin hook support for channel_deleted and emitted it from the Teams monitor on channelDeleted
  • pruned archived conversation state when Teams emits channel deletion lifecycle events
  • kept the existing Graph-based cleanup sweep as a backstop for older/archive-state records
  • added changelog entries and focused regression tests for archive storage, cleanup, Teams handler dispatch, and hook runner wiring

Validation

  • pnpm vitest run src/plugins/wired-hooks-message.test.ts extensions/msteams/src/monitor-handler.file-consent.test.ts extensions/msteams-channel-archive/index.test.ts extensions/msteams-channel-archive/src/archive-store.test.ts extensions/msteams-channel-archive/src/channel-cleanup.test.ts src/hooks/message-hook-mappers.test.ts
  • validated on the Azure Teams gateway node with a fresh channel message followed by a restorable channel delete; the runtime logged channelDeleted and pruned the new channel archive successfully

Notes

  • repo-wide pnpm build still hits pre-existing baseline failures in src/agents/** and src/commands/openai-codex-oauth.ts
  • the Azure node is now configured to run the latest checkout via systemd for continued validation

Copilot AI review requested due to automatic review settings March 11, 2026 13:03
@openclaw-barnacle openclaw-barnacle Bot added channel: msteams Channel integration: msteams size: XL labels Mar 11, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Mar 11, 2026

Greptile Summary

This PR introduces a msteams-channel-archive extension that persistently archives Teams channel messages and attachments to local JSONL files, adds deleted-channel cleanup (both event-driven via channelDeleted and periodic via Graph), and enriches the inbound hook metadata (reply chain, team/channel IDs, provider metadata) so downstream plugins receive richer context.

Key highlights:

  • New msteams-channel-archive plugin — JSONL-backed message store with attachment deduplication, content-hash storage, and four query tools (search, get-message, get-thread, search-attachments).
  • channel_deleted plugin hook — new lifecycle hook dispatched from the Teams monitor when a conversationUpdate/channelDeleted event arrives; the archive plugin prunes the deleted channel's data in response.
  • Graph attachment improvements/chats/ fallback URLs for channel threads where teamId is not a UUID, plus /$value fetching for hosted content whose bytes aren't inlined in the collection response.
  • Three issues found:
    • DEFAULT_MEDIA_AUTH_HOST_ALLOWLIST adds "trafficmanager.net" (suffix-matched), causing Bearer tokens to be forwarded to any *.trafficmanager.net host rather than just the intended smba.trafficmanager.net.
    • archiveAttachments is called outside the index file lock, creating a TOCTOU race with pruneConversation that can leave a message record referencing a deleted attachment.
    • onlyHtmlAttachments is now set with some() instead of every() — the variable name is misleading after this intentional semantic change.

Confidence Score: 3/5

  • Mostly safe but has a credential-scope widening in the auth allowlist and a TOCTOU race in the archive store that should be addressed before merging.
  • The PR is well-structured, thoroughly tested, and the overall design is sound. However, the trafficmanager.net entry in DEFAULT_MEDIA_AUTH_HOST_ALLOWLIST broadens token forwarding to any *.trafficmanager.net host (a large Azure-wide namespace) instead of the specific smba.trafficmanager.net — a meaningful security regression. The TOCTOU race between archiveAttachments and pruneConversation is narrow in practice but can produce silently broken archive records. These two issues lower confidence below a straight merge.
  • extensions/msteams/src/attachments/shared.ts (auth allowlist scope) and extensions/msteams-channel-archive/src/archive-store.ts (attachment copy vs. lock ordering) need attention before merging.

Comments Outside Diff (1)

  1. extensions/msteams-channel-archive/src/archive-store.ts, line 671-746 (link)

    TOCTOU race between archiveAttachments and pruneConversation

    archiveAttachments (which physically copies files to the attachment store) is called before the file lock is acquired. The lock is only taken when writing the message record and updating the index. This creates a race:

    1. Thread A calls archiveAttachments and copies attachment → attachments/ab/ab<sha>/file.bin (no lock held).
    2. Thread B calls pruneConversation under the lock, collects all referenced attachment paths from the current index (which doesn't include Thread A's not-yet-written message), and deletes attachments/ab/ab<sha>/file.bin as "unreferenced".
    3. Thread A acquires the lock, writes a message record whose storedPath points to the now-deleted file.

    The result is a message record that permanently references a missing attachment with no way to recover it. The missing: true flag in withAttachmentStatus will surface this, but the data is gone.

    The simplest mitigation is to move the archiveAttachments call inside the lock body so the file's reference is recorded atomically with the copy, or alternatively reverse the pruning logic so it only removes a file after confirming no in-flight writers could reference it (e.g., by re-scanning the index after the message file has been written).

    Prompt To Fix With AI
    This is a comment left during a code review.
    Path: extensions/msteams-channel-archive/src/archive-store.ts
    Line: 671-746
    
    Comment:
    **TOCTOU race between `archiveAttachments` and `pruneConversation`**
    
    `archiveAttachments` (which physically copies files to the attachment store) is called **before** the file lock is acquired. The lock is only taken when writing the message record and updating the index. This creates a race:
    
    1. Thread A calls `archiveAttachments` and copies attachment → `attachments/ab/ab<sha>/file.bin` (no lock held).
    2. Thread B calls `pruneConversation` under the lock, collects all referenced attachment paths from the current index (which doesn't include Thread A's not-yet-written message), and deletes `attachments/ab/ab<sha>/file.bin` as "unreferenced".
    3. Thread A acquires the lock, writes a message record whose `storedPath` points to the now-deleted file.
    
    The result is a message record that permanently references a missing attachment with no way to recover it. The `missing: true` flag in `withAttachmentStatus` will surface this, but the data is gone.
    
    The simplest mitigation is to move the `archiveAttachments` call inside the lock body so the file's reference is recorded atomically with the copy, or alternatively reverse the pruning logic so it only removes a file after confirming no in-flight writers could reference it (e.g., by re-scanning the index *after* the message file has been written).
    
    How can I resolve this? If you propose a fix, please make it concise.

Last reviewed commit: 8155db0

Comment thread extensions/msteams/src/attachments/shared.ts Outdated
Comment thread extensions/msteams/src/monitor-handler/inbound-media.ts Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a new Microsoft Teams channel-archive extension and wires new lifecycle/metadata plumbing so plugins can persist Teams channel history (including attachments) and clean up archived state when a channel is deleted.

Changes:

  • Introduces extensions/msteams-channel-archive with JSONL-backed archive storage, attachment copying, and archive query tools.
  • Adds a new plugin hook (channel_deleted) and emits it from the Teams monitor on conversationUpdate/channelDeleted.
  • Enriches inbound message hook metadata with Teams-specific fields (reply/thread/media/provider metadata) to support archiving.

Reviewed changes

Copilot reviewed 24 out of 25 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/plugins/wired-hooks-message.test.ts Adds hook-runner regression test coverage for the new channel_deleted hook runner method.
src/plugins/types.ts Extends plugin hook names/types to include channel_deleted and defines its event type.
src/plugins/hooks.ts Adds runChannelDeleted to the hook runner implementation/export surface.
src/hooks/message-hook-mappers.ts Extends canonical inbound hook context and maps additional Teams/media/thread/provider fields into plugin event metadata.
src/hooks/message-hook-mappers.test.ts Updates tests to assert the new mapped metadata fields.
src/auto-reply/templating.ts Adds ProviderMetadata to message context typing for provider-specific untrusted metadata propagation.
pnpm-lock.yaml Adds dependency lock entries for the new extension workspace.
extensions/msteams/src/monitor-handler/message-handler.ts Enriches inbound message context with Teams provider metadata (team/channel IDs, replyToId, etc.).
extensions/msteams/src/monitor-handler/inbound-media.ts Adjusts Graph fallback triggering logic for HTML attachments when no media downloaded.
extensions/msteams/src/monitor-handler.ts Emits channel_deleted hook on Teams conversationUpdate/channelDeleted events via the global hook runner.
extensions/msteams/src/monitor-handler.file-consent.test.ts Adds test coverage verifying channelDeleted events are forwarded to plugin hooks.
extensions/msteams/src/attachments/shared.ts Extends auth-host allowlist for attachment downloads.
extensions/msteams/src/attachments/graph.ts Adds /chats/ URL fallbacks and improves hosted-content download by fetching $value when contentBytes isn’t inlined.
extensions/msteams-channel-archive/src/types.ts Defines archive store record types and search/prune result shapes.
extensions/msteams-channel-archive/src/tools.ts Registers archive query tools with TypeBox schemas and JSON-formatted responses.
extensions/msteams-channel-archive/src/channel-cleanup.ts Implements periodic Graph-based deleted-channel cleanup sweep and prune logic.
extensions/msteams-channel-archive/src/channel-cleanup.test.ts Adds unit tests for cleanup sweep pruning/skip behavior.
extensions/msteams-channel-archive/src/archive-store.ts Implements JSONL archive store, attachment copying, searching, listing, and pruning.
extensions/msteams-channel-archive/src/archive-store.test.ts Adds store tests for dedupe, search/thread queries, and prune/orphan-attachment removal behavior.
extensions/msteams-channel-archive/package.json Adds new extension package manifest and TypeBox dependency.
extensions/msteams-channel-archive/openclaw.plugin.json Declares plugin metadata and config schema for the new extension.
extensions/msteams-channel-archive/index.ts Wires the extension: registers tools/services, archives message_received, prunes on channel_deleted.
extensions/msteams-channel-archive/index.test.ts Adds basic extension wiring test for channel_deleted pruning.
CHANGELOG.md Adds changelog entries describing the Teams channel archive plugin and delete-event pruning.
.github/labeler.yml Adds GitHub label automation for the new extension path.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

Comment thread extensions/msteams/src/attachments/shared.ts Outdated
Comment thread extensions/msteams-channel-archive/src/channel-cleanup.ts
Comment thread extensions/msteams/src/monitor-handler/inbound-media.ts Outdated
Comment thread extensions/msteams-channel-archive/src/archive-store.ts Outdated
Comment thread extensions/msteams-channel-archive/src/archive-store.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 8155db0e99

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams/src/monitor-handler/message-handler.ts Outdated
Comment thread extensions/msteams-channel-archive/src/channel-cleanup.ts Outdated
@hddevteam
Copy link
Copy Markdown
Author

Follow-up pushed in f9d9f5086.

Addressed the substantive review items:

  • tightened the Teams media auth allowlist from trafficmanager.net to smba.trafficmanager.net
  • moved attachment archiving under the archive store lock to avoid the archive/prune race
  • preserved legacy Teams allowlist compatibility by checking the runtime team ID first and Graph team ID as an alternate key
  • fixed legacy deleted-channel cleanup fallback to resolve Graph team IDs using the archived channelId
  • renamed the HTML-attachment fallback flag to match the current behavior

Validation rerun:

  • pnpm vitest run extensions/msteams/src/policy.test.ts extensions/msteams/src/monitor-handler.file-consent.test.ts extensions/msteams-channel-archive/src/channel-cleanup.test.ts extensions/msteams-channel-archive/src/archive-store.test.ts src/hooks/message-hook-mappers.test.ts src/plugins/wired-hooks-message.test.ts extensions/msteams-channel-archive/index.test.ts

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f9d9f50866

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams/src/attachments/graph.ts Outdated
Comment thread extensions/msteams-channel-archive/src/channel-cleanup.ts
@hddevteam
Copy link
Copy Markdown
Author

Addressed second round of review feedback in commit 872be20:

Fixed (4 issues):

  1. JSONL error tolerance (archive-store.ts) — parseJsonLine now returns null on malformed lines and the caller filters them out with a console.warn; a single corrupt line no longer breaks all reads for that archive.

  2. Bounded top-N search (archive-store.ts) — searchMessages and searchAttachments now maintain an O(limit)-memory bounded accumulator instead of collecting all matches and sorting at the end. This avoids unbounded allocations when archives are large and limit is small.

  3. Graph team discovery cache (channel-cleanup.ts) — runArchiveCleanupSweep now caches teamId::channelId → graphTeamId across the per-archive loop so a full-tenant Graph scan is only performed once per distinct key per sweep, not once per archived channel.

  4. maxBytes guard before buffering (graph.ts) — Checks content-length before calling arrayBuffer() on hosted-content /$value responses; oversized payloads are skipped without being materialized.

Outdated thread (P2 — compare archive channel ID when resolving Graph team) was already fixed in the previous commit (f9d9f5086) — resolveGraphTeamIdForArchive now compares channel.id against archive.channelId, not teamRuntimeId.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 872be2053a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams-channel-archive/index.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: c074e4418a

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams-channel-archive/src/channel-cleanup.ts Outdated
Comment thread extensions/msteams-channel-archive/src/channel-cleanup.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 36b16dc3d0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams/src/monitor-handler/message-handler.ts Outdated
Comment thread extensions/msteams-channel-archive/src/channel-cleanup.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b7d8ec6912

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams/src/monitor-handler.ts Outdated
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0475260e00

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams/src/monitor-handler.ts Outdated
Comment thread extensions/msteams-channel-archive/src/channel-cleanup.ts
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b8d4caedfd

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams-channel-archive/src/channel-cleanup.ts Outdated
@hddevteam
Copy link
Copy Markdown
Author

hddevteam commented Mar 16, 2026

TL;DR for reviewers following the stack:

The child PR is framing this as a default-policy fix, not a replyToId loss bug.

  • mention gating (requireMention) and reply destination (replyStyle) are separate concerns
  • channel replies should still default to thread
  • creating a new post should only happen with an explicit replyStyle: "top-level" override

Follow-up validation run:

  • pnpm test -- extensions/msteams/src/policy.test.ts extensions/msteams/src/messenger.test.ts

@hddevteam hddevteam force-pushed the feat/msteams-channel-archive branch from 1272481 to 173dbc5 Compare March 17, 2026 06:41
Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 173dbc5782

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread extensions/msteams/src/monitor.ts Outdated
@clawsweeper
Copy link
Copy Markdown
Contributor

clawsweeper Bot commented Apr 28, 2026

Codex review: needs changes before merge.

Summary
The PR adds a bundled msteams-channel-archive plugin, Teams channel_deleted hook wiring, inbound Teams metadata propagation, archive cleanup/storage tests, labeler/changelog updates, and SDK baseline changes.

Reproducibility: not applicable. as a feature PR rather than a user bug report. The blocking findings are source-reproducible by comparing PR head d019bf0b4df9 with current main's manifest, activation, and tool-registration contracts.

Next step before merge
The remaining actionable blockers are narrow manifest/docs repairs suitable for an automated repair pass; final merge still needs maintainer approval for the new archive and hook surface.

Security
Cleared: The latest diff adds local archive storage, Graph cleanup, private package metadata, and lockfile entries; earlier token-scope, lock-ordering, and size-guard concerns appear addressed, and I found no concrete remaining security or supply-chain regression.

Review findings

  • [P2] Declare the archive tools in the manifest — extensions/msteams-channel-archive/openclaw.plugin.json:2-3
  • [P2] Declare startup activation for archive capture — extensions/msteams-channel-archive/openclaw.plugin.json:2-3
  • [P3] Document the new channel_deleted hook — src/plugins/hook-types.ts:86
Review details

Best possible solution:

Land a reviewed version that declares the archive plugin's activation and tool ownership metadata, documents the new hook contract, keeps the Teams archive behavior plugin-owned, and passes the targeted plugin/Teams checks plus the changed gate.

Do we have a high-confidence way to reproduce the issue?

Not applicable as a feature PR rather than a user bug report. The blocking findings are source-reproducible by comparing PR head d019bf0b4df9 with current main's manifest, activation, and tool-registration contracts.

Is this the best way to solve the issue?

No for the PR exactly as submitted. The implementation direction is plausible, but the manifest must declare startup activation and registered tool contracts, and the public hook docs should be aligned before normal maintainer approval.

Full review comments:

  • [P2] Declare the archive tools in the manifest — extensions/msteams-channel-archive/openclaw.plugin.json:2-3
    This plugin registers four archive query tools, but the manifest declares no contracts.tools. Current registerTool treats an empty tool contract list as an error and returns, so channel_archive_search, channel_archive_get_message, channel_archive_get_thread, and channel_archive_search_attachments will not register. Add those names to contracts.tools.
    Confidence: 0.95
  • [P2] Declare startup activation for archive capture — extensions/msteams-channel-archive/openclaw.plugin.json:2-3
    The archive capture hooks and cleanup service are installed only when register(...) runs, but this manifest has no activation.onStartup. Current docs say omitted startup activation no longer startup-loads a plugin, and the bundled manifest test requires an explicit boolean, so Teams archive capture and deletion cleanup can stay inactive. Add activation.onStartup: true or an equivalent tested activation path that loads this plugin before Teams messages arrive.
    Confidence: 0.92
  • [P3] Document the new channel_deleted hook — src/plugins/hook-types.ts:86
    This adds channel_deleted to the exported hook surface, but docs/plugins/hooks.md still documents only the existing message hooks. Since the PR updates the SDK baseline for a new public hook, add a short docs entry describing when it fires and the event metadata shape.
    Confidence: 0.82

Overall correctness: patch is incorrect
Overall confidence: 0.9

Acceptance criteria:

  • pnpm test -- src/plugins/contracts/plugin-tool-contracts.test.ts src/plugins/bundled-plugin-metadata.test.ts
  • pnpm test -- src/plugins/wired-hooks-message.test.ts src/hooks/message-hook-mappers.test.ts
  • pnpm test -- extensions/msteams/src/monitor-handler.file-consent.test.ts extensions/msteams/src/policy.test.ts extensions/msteams/src/messenger.test.ts
  • pnpm test -- extensions/msteams-channel-archive/index.test.ts extensions/msteams-channel-archive/src/archive-store.test.ts extensions/msteams-channel-archive/src/channel-cleanup.test.ts
  • pnpm exec oxfmt --check --threads=1 CHANGELOG.md docs/plugins/hooks.md extensions/msteams-channel-archive/openclaw.plugin.json

What I checked:

  • Current main lacks archive plugin: Current main only has extensions/msteams; there is no extensions/msteams-channel-archive directory or archive tool implementation. (a7c5a0425988)
  • Current main lacks channel_deleted hook: PluginHookName and PLUGIN_HOOK_NAMES include message_received, message_sending, and message_sent, but no channel_deleted hook. (src/plugins/hook-types.ts:70, a7c5a0425988)
  • Latest PR head confirmed: GitHub API reports the PR head as d019bf0b4df96d7cbc56ad27f717232365d38835, updated 2026-05-03, with mergeable: false. (d019bf0b4df9)
  • PR manifest omits activation and tool contracts: The archive plugin manifest contains only id and configSchema; it does not declare activation.onStartup or contracts.tools. (extensions/msteams-channel-archive/openclaw.plugin.json:2, d019bf0b4df9)
  • PR runtime work only happens after plugin load: The plugin registers archive tools, cleanup service, message_received, and channel_deleted handlers inside register(...). (extensions/msteams-channel-archive/index.ts:62, d019bf0b4df9)
  • PR registers undeclared tools: The PR registers channel_archive_search, channel_archive_get_message, channel_archive_get_thread, and channel_archive_search_attachments. (extensions/msteams-channel-archive/src/tools.ts:93, d019bf0b4df9)

Likely related people:

  • shakkernerd: Recent history shows related work enforcing plugin tool manifest contracts and explicit bundled startup metadata, which are the central blockers in this PR. (role: manifest contract owner; confidence: high; commits: 7641783d6b0e, 13987b726aa6, 6f139822127a; files: src/plugins/registry.ts, docs/plugins/building-plugins.md, src/plugins/bundled-plugin-metadata.test.ts)
  • steipete: Recent commits touch MS Teams hot paths and plugin activation/tool discovery docs/runtime, making this a likely review route for the Teams plus plugin loader boundary. (role: recent maintainer; confidence: high; commits: 3f002b10d281, 7ac23eeeb581, baadd74b6bb5; files: extensions/msteams/src/monitor-handler.ts, docs/plugins/manifest.md, docs/plugins/building-plugins.md)
  • vincentkoc: Recent commits touch plugin registry/hook metadata and message-hook mapper seams, which overlap the PR's hook and metadata propagation changes. (role: adjacent owner; confidence: medium; commits: 1d34564de9ba, 1b25dcf57a9f, e593122465e7; files: src/plugins/registry.ts, src/plugins/hook-types.ts, src/hooks/message-hook-mappers.ts)

Remaining risk / open question:

  • GitHub API currently reports mergeable: false, so the source branch may need a rebase or replacement branch in addition to the code repairs.
  • This PR adds a persistent bundled archive plugin plus a new public hook surface, so maintainers still need product/ownership approval after the mechanical blockers are fixed.
  • No local test run was performed in this read-only sweep; the blockers are source-level checks against current main and the latest PR head.

Codex review notes: model gpt-5.5, reasoning high; reviewed against a7c5a0425988.

@hddevteam hddevteam force-pushed the feat/msteams-channel-archive branch 2 times, most recently from dde9d2d to c62d7c1 Compare April 29, 2026 00:40
@openclaw-barnacle openclaw-barnacle Bot added the docs Improvements or additions to documentation label Apr 29, 2026
@hddevteam hddevteam force-pushed the feat/msteams-channel-archive branch from c62d7c1 to d892540 Compare April 29, 2026 01:09
Ming and others added 2 commits April 29, 2026 09:18
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Ming and others added 6 commits April 29, 2026 09:18
- archive-store: tolerate malformed JSONL lines (skip + warn instead of throw)
- archive-store: bounded top-N accumulator in searchMessages/searchAttachments
  avoids O(n) memory with large archives; O(limit) memory instead
- channel-cleanup: cache Graph team/channel resolution across archives in
  one sweep to avoid N× full-tenant Graph scan per archived channel
- graph: check content-length header before materialising hosted-content
  arrayBuffer to prevent large allocations beyond maxBytes

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

channel: msteams Channel integration: msteams docs Improvements or additions to documentation size: XL triage: refactor-only Candidate: refactor/cleanup-only PR without maintainer context.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants