# Open spec questions Structured questions raised in flight by the team. Each entry is a candidate for team-lead escalation **before** code touches the area. Resolved questions move to `spec-decisions.md` (with a `D-NNN` id) and are deleted from here. Format: - **Q-NNN** — one-line title - **Where it bites**: the F* or §-anchor in the spec - **What is silent**: the precise gap - **Options**: numbered alternatives with tradeoffs - **Recommended default if no decision**: the safest path forward - **Status**: `open` / `deferred — re-open when …` / resolved entries are moved to `spec-decisions.md` --- ## Q-003 — `/engagements/:id/hosts/sync` merge semantics - **Status**: **deferred** — re-open when F4 sync endpoint lands (post-sprint-0, needs PR1 closed). - **Where it bites**: F4 + §9 endpoint `/engagements/:id/hosts/sync`. - **What is silent**: - Merge vs replace: do hosts that disappear from C2 get deleted, marked `status = "stale"`, or kept untouched? - What if a manually-added host conflicts (same hostname, different `c2_session_id`)? - Source of truth: the C2 session ID, the hostname, the IP, a tuple? - Cascading effect: a `host` referenced by `scenario_step.host_id` deleted mid-engagement breaks the scenario silently. - **Options**: 1. **Merge + mark stale**: insert new, update changed, mark missing as `status = "stale"` (never delete). Conflicts: manual entry wins, C2-synced entry is appended with a suffix and an audit_log entry. 2. **Replace**: delete all sync-sourced rows, reinsert from C2. Manual entries kept untouched. Simple but loses history. 3. **Merge by tuple `(hostname, c2_session_id)`** with status tracking, conflicts always raise and require manual resolution UI. - **Recommended default if no decision**: option 1. Stale > deleted: a deleted host breaks `scenario_step.host_id` and the audit trail. Conflict policy: manual wins, C2 entry suffixed and audit-logged. ## Q-004 — `payload_type` → C2 home command mapping (depends on PR2) - **Status**: **deferred** — re-open with PR2 (internal C2 interface spec). - **Where it bites**: §7 enum `payload_type`, right column "C2 maison" is fully TBD; F2 import journal C2 home parser; B0.4 `C2Connector` factory. - **What is silent**: entirety of the C2 home mapping table, plus the exact return semantics of `HomeConnector.execute_task / get_task_result / cancel_task / execute_cleanup` (PR2). - **Options**: no in-flight options — this is owned by PR2. - **Recommended default if no decision**: keep `HomeConnector` as a stub that raises `NotImplementedError` (per B0.4: "no real implementation"). Block any attempt to ship `HomeConnector` v1 logic until PR2 is closed. ## Q-005 — Stale-host policy after engagement archival - **Status**: **deferred** — re-open with the F12 archival CLI. - **Where it bites**: §8 `host.status`, engagement lifecycle, F12. - **What is silent**: when an engagement is archived, what happens to its hosts? Detach session, freeze status, leave as-is? - **Options**: 1. Set `host.status = "archived"` cascading from `engagement.status`. 2. Keep status untouched, rely on `engagement.status` upstream. - **Recommended default if no decision**: option 2 — engagement state is the single source of truth, hosts inherit by JOIN. --- ## Resolved (moved to `spec-decisions.md`) - Q-001 → **D-011** — `regex_extract` Jinja2 filter semantics. - Q-002 → **D-012** — `output_blob_ref` storage layout.