feat: filter receive messages by since
This commit is contained in:
@@ -26,7 +26,7 @@ Remote base before local roadmap commits: `b2d839e Merge branch 'codex/n15-repor
|
||||
- C# `ISphereWinHelper` exists under `native/ISphereWinHelper` and uses the `isphere.helper.v1` stdin/stdout JSON contract.
|
||||
- `scripts/verify-win-helper.ps1` and `scripts/verify-go-mcp.ps1` provide repeatable local checks for the helper, eight-tool MCP surface, default empty-source receive/contact/group/file calls, synthetic configured-file receive/contact/group/file smoke, and synthetic configured-directory receive/contact/group/file smoke.
|
||||
- `isphere_receive_messages` now returns the contract-facing `ok`, `conversation`, `messages`, `next_cursor`, and `audit` envelope while retaining legacy parser-native message fields for compatibility.
|
||||
- `isphere_receive_messages` accepts `conversation_id`, `query`, and `limit` for local readonly PacketReader evidence filtering.
|
||||
- `isphere_receive_messages` accepts `conversation_id`, `query`, `since`, and `limit` for local readonly PacketReader evidence filtering.
|
||||
- N12-pre and N12R documents define safe offline evidence intake and internal-sandbox live UIA capture procedures.
|
||||
- N13/N14/N15 produced selector catalog/report validation infrastructure, but those are supporting validation assets only.
|
||||
|
||||
@@ -53,7 +53,7 @@ N13/N14/N15 are pre-business validation results. They can help identify UI eleme
|
||||
|
||||
## Current loop
|
||||
|
||||
Current loop: `Stage C / Loop C19 - receive-message since time filter slice`.
|
||||
Current loop: `Stage C / Loop C20 - receive-message remaining contract argument validation`.
|
||||
|
||||
Plan file: `docs/superpowers/plans/2026-07-09-stage-c-log-backed-receive-messages-loop.md`.
|
||||
|
||||
@@ -84,10 +84,11 @@ Current loop output so far:
|
||||
16. C16: configured PacketReader source hardening added `ISPHERE_PACKET_LOG_DIR`, deterministic recursive `.log`/`.txt` directory loading, ambiguous file/dir config failure, and configured-directory receive/contact/group/file smoke verification.
|
||||
17. C17: `isphere_receive_messages` output was aligned to the core read contract envelope and message fields while retaining legacy aliases; verify-go-mcp now asserts contract fields for configured file and directory source smokes.
|
||||
18. C18: `isphere_receive_messages` gained `conversation_id` and `query` filters across source, MCP args, tests, and configured file/directory smoke verification.
|
||||
19. C19: `isphere_receive_messages` gained RFC3339 `since` filtering against PacketReader epoch-millisecond timestamps plus invalid-since error handling.
|
||||
|
||||
## Next business mainline
|
||||
|
||||
1. Run Stage C Loop C19: add the next safe `isphere_receive_messages` filter (`since`) so digital employees can target recent configured local-readonly evidence by time.
|
||||
1. Run Stage C Loop C20: accept and validate the remaining safe `isphere_receive_messages` contract arguments (`include_attachment_metadata`, `source_preference`, `preview`, and empty `cursor`) without pretending unsupported connectors/pagination exist.
|
||||
2. Leave `isphere_send_message` blocked until bridge/API, UIA action-chain, or protocol connector evidence is validated.
|
||||
3. Leave actual file download/cache mapping as a later connector node until a message-to-cache hash or client download source is validated.
|
||||
4. Keep UIA selector/report work as fallback support, not as the primary roadmap.
|
||||
|
||||
@@ -184,7 +184,7 @@ Allowed parameters:
|
||||
- `win_helper_self_check`: zero business parameters.
|
||||
- `win_helper_scan_windows`: `include_all_visible` only.
|
||||
- `win_helper_dump_uia`: `hwnd`, `max_depth`, `include_text`, `max_children` only.
|
||||
- `isphere_receive_messages`: `conversation_id`, `query`, `limit` only.
|
||||
- `isphere_receive_messages`: `conversation_id`, `query`, `since`, `limit` only. `since` must be RFC3339/RFC3339Nano when supplied.
|
||||
- `isphere_search_contacts`: `query`, `limit` only.
|
||||
- `isphere_search_groups`: `query`, `limit` only.
|
||||
- `isphere_receive_files`: `conversation_id`, `message_id`, `file_id`, `name_contains`, `mode`, `limit` only. C14 supports `mode` empty or `list`; download is deferred.
|
||||
@@ -202,7 +202,7 @@ The current runbook verifies eight tools:
|
||||
- `isphere_search_groups`
|
||||
- `isphere_receive_files`
|
||||
|
||||
The current log-backed business read tools have parser/source/tool registration and an empty default server source. Raw N12-pre evidence remains under ignored `runs/` paths and is not committed. The current command entry point can read an operator-local encrypted PacketReader log-line file via `ISPHERE_PACKET_LOG_FILE` or a directory of `.log`/`.txt` files via `ISPHERE_PACKET_LOG_DIR`; this is still not a production ingestion claim because raw evidence remains local and uncommitted. `isphere_receive_messages` now exposes contract-facing fields for digital-employee consumption while preserving older aliases for compatibility, and supports `conversation_id` plus keyword `query` filtering. `isphere_receive_files` currently supports list mode only; download/cache mapping is deferred.
|
||||
The current log-backed business read tools have parser/source/tool registration and an empty default server source. Raw N12-pre evidence remains under ignored `runs/` paths and is not committed. The current command entry point can read an operator-local encrypted PacketReader log-line file via `ISPHERE_PACKET_LOG_FILE` or a directory of `.log`/`.txt` files via `ISPHERE_PACKET_LOG_DIR`; this is still not a production ingestion claim because raw evidence remains local and uncommitted. `isphere_receive_messages` now exposes contract-facing fields for digital-employee consumption while preserving older aliases for compatibility, and supports `conversation_id`, keyword `query`, and RFC3339 `since` filtering. `isphere_receive_files` currently supports list mode only; download/cache mapping is deferred.
|
||||
|
||||
Core business tools for contacts, groups, messages, and files are defined in `docs/mcp-core-tools-contract.md`. Send capabilities enter the roadmap through that contract after source discovery, connector selection, preview metadata, execution metadata, and audit records are in place.
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ Schema notes: `docs/source-discovery/2026-07-09-n12-pre-zyl-schema-notes.md`
|
||||
|
||||
| MCP tool | Primary source | Fallback source | Evidence file | Decision status | Next implementation slice |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| `isphere_receive_messages` | decrypted `PacketReader.ProcessPacket` XMPP `<message>` stanzas via `internal/isphere.EncryptedPacketLogSource`; configured by `ISPHERE_PACKET_LOG_FILE` or `ISPHERE_PACKET_LOG_DIR` | decrypted `Smark.SendReceive` transport stanzas; decrypted `SaveToDB` `Chat_OnMessageArrived` traces; wrapped `MsgLib.db` after DB wrapper is solved | `docs/source-discovery/2026-07-09-n12-pre-zyl-schema-notes.md#field-mapping-evidence` | C18 supports contract-shaped output plus `conversation_id`, `query`, and `limit` filters; default source remains empty when unset | add `since` time filter |
|
||||
| `isphere_receive_messages` | decrypted `PacketReader.ProcessPacket` XMPP `<message>` stanzas via `internal/isphere.EncryptedPacketLogSource`; configured by `ISPHERE_PACKET_LOG_FILE` or `ISPHERE_PACKET_LOG_DIR` | decrypted `Smark.SendReceive` transport stanzas; decrypted `SaveToDB` `Chat_OnMessageArrived` traces; wrapped `MsgLib.db` after DB wrapper is solved | `docs/source-discovery/2026-07-09-n12-pre-zyl-schema-notes.md#field-mapping-evidence` | C19 supports contract-shaped output plus `conversation_id`, `query`, `since`, and `limit` filters; default source remains empty when unset | validate remaining safe contract args |
|
||||
| `isphere_search_contacts` | bare sender/receiver JIDs extracted from normalized log-backed messages loaded from configured PacketReader file or directory source | decrypted roster/contact stanzas from `Smark.SendReceive`; `MsgLib.db` contact/conversation tables after DB wrapper is solved; UIA helper source if display names are missing | `docs/source-discovery/2026-07-09-n12-pre-zyl-schema-notes.md#log-decryption-result` | C16 verification covers default, configured-file, and configured-directory contact smoke; JID-only display/account fallback | enrich display names from roster/db/uia evidence |
|
||||
| `isphere_search_groups` | decrypted `PacketReader.ProcessPacket` `type="groupchat"` stanzas and conference/MUC JIDs loaded from configured PacketReader file or directory source | `MsgLib.db` group/conversation tables after DB wrapper is solved; UIA helper source if group display names are missing | C9 ignored-log scan: PacketReader 86 groupchat/86 conference hits; Smark 24 groupchat/658 conference/631 muc hits | C16 verification covers default, configured-file, and configured-directory group smoke; JID-only display fallback | enrich group display/member data from roster/db/uia evidence |
|
||||
| `isphere_receive_files` | decrypted `PacketReader.ProcessPacket` file-transfer message stanzas via `internal/isphere.ListFilesFromMessages` and `isphere_receive_files` list mode; configured PacketReader file or directory source; `zyl\importal\<hash>` cache entries remain unlinked | decrypted `Smark.SendReceive` and `SaveToDB` traces for file-reference reconciliation; future UIA/client connector for download | `docs/source-discovery/2026-07-09-n12-pre-zyl-schema-notes.md#c12-file-transfer-evidence-precheck` | C16 verification covers default, configured-file, and configured-directory file-list smoke; no log-to-cache/download mapping yet | defer download mapping; align read-tool contract output |
|
||||
|
||||
@@ -1634,19 +1634,19 @@ Implemented and verified in this loop:
|
||||
- Keep `cursor`, `source_preference`, and broader pagination deferred.
|
||||
- Do not add write/send/file-download behavior.
|
||||
|
||||
- [ ] **Step 1: Write failing source `since` test**
|
||||
- [x] **Step 1: Write failing source `since` test**
|
||||
|
||||
Use synthetic PacketReader fixtures before and after an RFC3339 threshold.
|
||||
|
||||
- [ ] **Step 2: Implement source `since` filtering**
|
||||
- [x] **Step 2: Implement source `since` filtering**
|
||||
|
||||
Parse `since` once per receive call and filter normalized messages by timestamp.
|
||||
|
||||
- [ ] **Step 3: Wire MCP args and verification**
|
||||
- [x] **Step 3: Wire MCP args and verification**
|
||||
|
||||
Expose `since` on `isphere_receive_messages`, update tool tests and `verify-go-mcp.ps1` synthetic smoke.
|
||||
|
||||
- [ ] **Step 4: Run full verification and commit**
|
||||
- [x] **Step 4: Run full verification and commit**
|
||||
|
||||
Run:
|
||||
|
||||
@@ -1661,6 +1661,65 @@ Expected: all exit 0. Remove any generated root `isphere-mcp.exe` after build. C
|
||||
|
||||
---
|
||||
|
||||
## Loop C19 Result
|
||||
|
||||
Implemented and verified in this loop:
|
||||
|
||||
- `isphere.ReceiveMessagesQuery` now supports `Since` in addition to `ConversationID`, `Query`, and `Limit`.
|
||||
- `EncryptedPacketLogSource.ReceiveMessages` accepts RFC3339/RFC3339Nano `since` input, compares it against PacketReader epoch-millisecond message timestamps, and returns only messages at or after the threshold.
|
||||
- Invalid `since` input now returns an explicit error instead of being silently ignored.
|
||||
- `isphere_receive_messages` MCP args now accept `since` and pass it through to the source.
|
||||
- `scripts/verify-go-mcp.ps1` now calls configured file and directory source smokes with `conversation_id`, `query`, and `since`.
|
||||
|
||||
---
|
||||
|
||||
## Loop C20: Receive-message remaining contract argument validation
|
||||
|
||||
**Goal:** Make `isphere_receive_messages` friendlier to contract-following digital employees by accepting the remaining safe read-contract parameters with explicit validation, while keeping unsupported pagination/source behavior honest.
|
||||
|
||||
**Planned files:**
|
||||
- Modify: `internal/tools/isphere_read.go`
|
||||
- Modify: `internal/tools/isphere_read_test.go`
|
||||
- Modify: `scripts/verify-go-mcp.ps1`
|
||||
- Modify: `docs/go-mcp-runbook.md`
|
||||
- Modify: `docs/current-status-card.md`
|
||||
- Modify: `docs/superpowers/plans/2026-07-09-stage-c-log-backed-receive-messages-loop.md`
|
||||
|
||||
**Planned behavior:**
|
||||
- Add MCP args for `include_attachment_metadata`, `source_preference`, `preview`, and `cursor`.
|
||||
- Accept `source_preference` empty, `auto`, or `local_readonly`; reject bridge/uia/network until those connectors exist.
|
||||
- Accept empty `cursor`; reject non-empty cursor until pagination is implemented.
|
||||
- Treat `preview` as read-only/no mutation and keep the audit `execution_mode` as `read`.
|
||||
- Treat `include_attachment_metadata=false` as a request to suppress inline receive-message attachments while leaving `isphere_receive_files` available for explicit file listing.
|
||||
- Do not add write/send/file-download behavior.
|
||||
|
||||
- [ ] **Step 1: Write failing MCP argument validation tests**
|
||||
|
||||
Extend `internal/tools/isphere_read_test.go` with accepted safe args and rejected unsupported source/cursor cases.
|
||||
|
||||
- [ ] **Step 2: Implement argument validation and attachment toggle**
|
||||
|
||||
Add minimal validation/helpers in `internal/tools/isphere_read.go`.
|
||||
|
||||
- [ ] **Step 3: Update verification and docs**
|
||||
|
||||
Update `scripts/verify-go-mcp.ps1`, runbook, status card, and this plan.
|
||||
|
||||
- [ ] **Step 4: Run full verification and commit**
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
git diff --check
|
||||
go test ./...
|
||||
go build ./cmd/isphere-mcp
|
||||
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/verify-go-mcp.ps1
|
||||
```
|
||||
|
||||
Expected: all exit 0. Remove any generated root `isphere-mcp.exe` after build. Commit exact C20 paths only and rewrite the next loop from actual results.
|
||||
|
||||
---
|
||||
|
||||
## Self-Review
|
||||
|
||||
- Spec coverage: the plan follows the user's cyclic requirement: plan first, implement one loop at a time, update the next loop after each result, and ask only on blockers.
|
||||
|
||||
Reference in New Issue
Block a user