# Spec: Nextcloud Talk assistant bridge

## Metadata
- Type: Spec
- Status: Draft
- Project: Nextcloud
- Created: 2026-05-14
- Updated: 2026-05-14

## Objective

Build a safe bridge that lets Deeso chat with Pi/the assistant from Nextcloud Talk and receive replies in the same conversation.

## Background

Nextcloud Talk is being enabled as part of the Nextcloud collaboration platform. The next step is not just human chat, but using Talk as an interface to the assistant for quick questions, task capture, operational requests, and coordination.

## Requirements

Must have:
- Receive messages from a designated Nextcloud Talk conversation.
- Send assistant replies back to the same conversation.
- Authenticate using a least-privilege account/app password.
- Restrict initial access to Deeso and the Pi/assistant account/conversation.
- Run the bridge on the Nextcloud VM.
- Support a small command set for reminders, project notes, ideas, and capture.
- Use a pending-draft approval flow: assistant proposes a draft, user replies `approve`, `edit: ...`, or `discard`.
- Store secrets outside this repository.
- Log enough for troubleshooting without leaking sensitive content unnecessarily.
- Document start/stop/test procedure.

Nice to have:
- Speech-to-text handling for voice notes, assuming Nextcloud/Talk exposes voice messages or attachments accessibly.
- Slash-command style controls, e.g. `capture`, `remind`, `project note`, `ticket`, `status`, `help`.
- Ability to append raw ideas to `inbox/capture.md`.
- Ability to create draft tickets after confirmation.
- Ability to create reminders in Nextcloud Tasks or Calendar, chosen ad hoc based on context.
- Local speech-to-text using Whisper/faster-whisper on the Nextcloud VM.
- Systemd service or containerized deployment.
- Health check and restart policy.

Out of scope:
- Public unauthenticated webhook endpoints.
- Voice/video assistant features.
- Broad multi-user access before the single-user flow is proven.
- Destructive sysadmin actions from chat without a separate approval/confirmation design.

## Users / Stakeholders

- Deeso: primary user sending Talk messages.
- Pi/assistant: chat participant and operator.
- Future users/collaborators: out of scope for first version.

## Proposed Design

Start with a small bridge service on the Nextcloud VM:

1. Authenticate to Nextcloud as the assistant account using an app password.
   - If `piagent` has elevated privileges, create a separate least-privilege Talk bot user instead.
2. Poll or subscribe to a single allowed Talk conversation.
3. For each new Deeso message, classify it as conversation, capture, reminder, project note, ticket request, or unsupported command.
4. Execute only approved v1 commands.
5. Post the assistant reply/confirmation back into the Talk conversation.
6. Maintain local state for last processed message IDs to avoid duplicate replies.

Initial v1 command/natural-language behavior:
- Support explicit commands for reliability: `capture`, `project note`, `remind`, `ticket`, `help`, `status`.
- Also support common natural-language intents such as "remind me...", "make a note...", "capture this...", and "create a ticket...".
- `capture`: create a pending draft capture/note first; apply to `inbox/capture.md` or another destination after confirmation/review.
- `project note`: create a pending draft project note first; apply to the appropriate project doc after confirmation/review.
- `remind`: create a pending draft reminder first; destination may be Nextcloud Tasks or Calendar depending on context, decided ad hoc.
- `ticket`: create a pending draft ticket first; ask for confirmation before moving it to active work.
- `help/status`: report available commands and bridge health.
- `pi` / `ask pi` / `move forward with`: create a pending assistant-request draft, then queue approved work requests to `Assistant/pi-requests.md` for Pi/human follow-up until direct assistant backend integration exists.

Pending draft review flow:
- For any durable change, the bridge posts a compact draft summary back to Talk.
- User replies `approve` to apply it.
- User replies `edit: <changes>` to revise the draft.
- User replies `discard` to cancel it.
- Only one active pending draft is allowed per conversation in v1 to avoid ambiguity.
- If a new command arrives while a draft is pending, the bridge should ask whether to approve/discard the current draft first.

Example reminder draft:

```text
Draft reminder:
Title: Pay bill
Destination: Tasks
Due: tomorrow
Reply approve, edit: ..., or discard.
```

Example capture draft:

```text
Draft capture:
Text: <captured idea>
Destination: inbox/capture.md
Reply approve, edit: ..., or discard.
```

Voice note handling:
- First confirm whether Talk voice messages are exposed as retrievable attachments/files through the Talk/OCS APIs.
- If available, download the audio attachment, transcribe it using local Whisper/faster-whisper on the Nextcloud VM, then process the transcript as if it were a text message.
- If not available in Talk, consider a fallback workflow using Nextcloud Files uploads to a watched folder.

Initial behavior should still be conservative:
- Do not execute infrastructure changes from chat until a separate approval model exists.
- For ambiguous or risky commands, ask for confirmation instead of acting.

## Infrastructure / Dependencies

Known:
- Nextcloud is the collaboration platform.
- Talk app is enabled: `spreed` 23.0.4.
- Nextcloud version is 33.0.3.
- Assistant account currently known as `piagent`.
- `piagent` is in the `ops` group, not the `admin` group, so v1 uses `piagent` for the bridge account.
- Pending draft state will be stored in JSON on the Nextcloud VM for v1 to keep migration/export simple.
- V1 prototype is deployed on the Nextcloud VM as `nextcloud-talk-assistant.service`.

Chosen bridge runtime location:
- Nextcloud VM.

Reasoning:
- Closest to the Talk service and can use local/LAN access.
- Keeps the chat bridge coupled to the collaboration platform.
- Requires care not to destabilize Nextcloud; prefer systemd service/container with clear resource limits and rollback.

Rejected/Deferred locations:
- This Pi workspace machine/repo context: easier repo-aware actions, but less directly tied to Talk runtime.
- Dedicated small VM/container: cleaner boundary, but more infrastructure overhead for v1.

Potential integration approaches to verify:
- Nextcloud Talk chat API polling.
- Talk bot framework/webhooks, if available in the installed Talk version.
- OCS API with app password authentication.

## Security / Safety

- Use least privilege; avoid admin account credentials.
- Prefer a dedicated app password scoped to the assistant account.
- Keep bridge LAN/Tailscale-only unless public exposure is separately reviewed.
- Restrict allowed conversations and users.
- Never store Nextcloud credentials, API keys, or app passwords in this repo.
- Require explicit confirmation before any destructive or security-sensitive operation requested via chat.
- Add rate limits or simple loop prevention so the bot cannot reply to itself indefinitely.

## Backup / Rollback Plan

- Before implementation, snapshot or back up any affected VM if installing services there.
- Bridge should be removable by stopping the service and revoking the app password.
- Keep implementation config separate from Nextcloud core configuration where possible.

## Open Questions

Answered:
- Run the bridge on the Nextcloud VM.
- If `piagent` has elevated privileges, create a dedicated least-privilege bot user.
- First version should support command execution for reminders, project information, ideas, and notes/capture.
- Explore speech-to-text for voice notes if supported by the installed Nextcloud/Talk setup.

Still open:
- What assistant backend/API is available for a long-running chat bridge?
- How should queued `Assistant/pi-requests.md` requests be pulled into this repository/session for execution and status updates?
- Is Talk API polling acceptable, or should we use webhooks/bot framework if available?
- What logging level is acceptable for chat contents?
- None currently for pending-draft storage; JSON on the Nextcloud VM is chosen for v1.

## Acceptance Criteria

This spec is satisfied when:
- [ ] Integration method is chosen.
- [ ] Bridge host/runtime is chosen.
- [ ] Authentication/account model is chosen.
- [ ] A single-conversation prototype can receive and reply.
- [ ] Operations/runbook documentation exists.
- [ ] Security boundaries are documented and accepted.

## Decisions

- Start single-user/single-conversation before expanding access.
- Run the first bridge on the Nextcloud VM.
- `piagent` is not a Nextcloud admin; use `piagent` for v1 Talk bridge auth. If it later gains elevated privileges, create a separate least-privilege bot user.
- V1 should support commands for reminders, project notes, ideas, and capture.
- Keep both Nextcloud Tasks and Calendar available for reminders; choose destination ad hoc based on context.
- Prefer local Whisper/faster-whisper on the Nextcloud VM for speech-to-text.
- V1 should create pending drafts first instead of directly modifying durable notes/tickets/reminders.
- Pending drafts use the commands `approve`, `edit: ...`, and `discard`.
- Allow only one active pending draft per conversation in v1.
- Store pending draft state in JSON on the Nextcloud VM for v1.
- Consider speech-to-text for voice notes if Talk exposes voice audio in a usable way.
- Do not allow destructive sysadmin actions from Talk in the first version.
- Do not store secrets in this repository.
