Update all operational references to reflect the new repo name per ADR-003 (OAS S1 Infrastructure Substrate). Historical text in ADRs and state-hub-inbox files preserved as-is. Gitea remote URL updated locally (Gitea repo rename is a manual step). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
89 lines
2.9 KiB
Markdown
89 lines
2.9 KiB
Markdown
---
|
|
type: feature-request
|
|
id: fr-2026-03-08--threephoenix--state-hub--offline-inbox-ingest
|
|
target_org: threephoenix
|
|
target_repo: state-hub
|
|
status: draft
|
|
created: "2026-03-08"
|
|
source_repo: railiance-infra
|
|
related_workstream_id: bf40b47e-be5b-4930-a7d2-362e76b943bb
|
|
---
|
|
|
|
# FR: Offline Inbox Ingest for Degraded-Mode Sessions
|
|
|
|
## Problem
|
|
|
|
When a Claude session runs on a remote host (e.g. HostEurope) without an active
|
|
SSH reverse tunnel, the State Hub MCP server is unreachable. Any progress events,
|
|
decision records, or task status updates that would normally be written via
|
|
`add_progress_event()` / `record_decision()` are silently lost unless the operator
|
|
manually replays them from their local machine after the session.
|
|
|
|
This creates a gap in the audit trail and requires manual follow-up that is easy
|
|
to forget.
|
|
|
|
## Proposed Solution
|
|
|
|
### 1. Inbox convention in domain repos
|
|
|
|
Domain repos write pending events to a `state-hub-inbox/` directory as YAML files:
|
|
|
|
```
|
|
state-hub-inbox/
|
|
YYYY-MM-DD-<slug>.yaml
|
|
```
|
|
|
|
Each file is a structured event:
|
|
|
|
```yaml
|
|
type: progress_event # or: decision, task_status_update
|
|
topic_id: <uuid>
|
|
workstream_id: <uuid>
|
|
event_type: milestone # matches add_progress_event() event_type values
|
|
summary: "..."
|
|
detail: {}
|
|
status: pending # state-hub sets to "ingested" after processing
|
|
recorded_at: "YYYY-MM-DD"
|
|
source_repo: <repo-slug>
|
|
```
|
|
|
|
Files are committed to git so they are never lost.
|
|
|
|
### 2. Ingest command in state-hub
|
|
|
|
Add a `make ingest-inbox` target (or equivalent CLI command) that:
|
|
|
|
1. Scans registered domain repos for `state-hub-inbox/*.yaml` files with `status: pending`
|
|
2. Calls the appropriate API endpoint for each (`add_progress_event`, `record_decision`, etc.)
|
|
3. Updates `status: ingested` and commits back (or opens a PR) so files are not replayed
|
|
|
|
Alternatively, the MCP server could expose a `ingest_inbox_file(path)` tool that
|
|
Claude calls at session start when the hub is reachable, to drain any queued events
|
|
from previous degraded sessions.
|
|
|
|
### 3. Session start behaviour
|
|
|
|
At orientation (Step 1), after `get_domain_summary()` succeeds, Claude should:
|
|
- Glob `state-hub-inbox/*.yaml` in the current repo
|
|
- For each file with `status: pending`, call the appropriate write tool and mark it ingested
|
|
|
|
This keeps the drain logic in Claude rather than requiring a separate make target.
|
|
|
|
## Acceptance Criteria
|
|
|
|
- `state-hub-inbox/` files with `status: pending` are reliably ingested on next
|
|
connected session with no manual intervention
|
|
- Ingested files are marked so they are not replayed
|
|
- Works for at minimum: `progress_event`, `decision`, `task_status_update`
|
|
|
|
## Example
|
|
|
|
See: `state-hub-inbox/2026-03-08-railiance01-bootstrap.yaml` in this repo —
|
|
the first real offline event that motivated this request.
|
|
|
|
## Priority
|
|
|
|
Medium. The workaround (manual replay) works but degrades auditability for
|
|
sessions run from remote hosts, which is the intended production workflow for
|
|
this project.
|