Skip to content

ADR 0016 — Operator Feedback Channel (airgap-safe)

  • Status: Accepted (locked 2026-05-08, formalized 2026-05-09)
  • Date: 2026-05-08
  • Deciders: TLSStress.Art project
  • Targets: v4.7+
  • Source memo: discuss_feedback_channel_2026_05_08.md

Context

The bench runs in operator-owned environments — many fully airgap. Today there is no first-class way for an operator to send a "wish", report a bug, or request a vendor addition without breaking out of the dashboard, finding our GitHub, and learning the issue-template conventions. Most operators won't do that. The result: feedback loop is broken; HQ has no signal on what operators actually need.

User confirmed 2026-05-08 with a Cisco Meraki feedback-modal screenshot as the reference UX. Meraki's modal is intentionally simple — placeholder examples ("Tell us about a feature you need", "Report a bug", "Suggest a vendor") guide the operator without forcing categories.

Decision

Ship a 3-layer feedback channel that is airgap-safe by design:

  Dashboard UI ──────► local SQLite queue ──────► Cloner egress ──────► HQ endpoint
  (operator types)     (encrypted at rest)        (Function 3:           (curated by
                                                   feedback-push)         humans + filed
                                                                          to GitHub)

Architecture invariants:

  • The dashboard never reaches HQ directly. The operator-side cloner is the only egress component (per Cloner-as-Platform principle); feedback-push is Function 3 of the cloner platform.
  • Local SQLite queue persists across pod restarts. Operator can inspect or delete entries before they're flushed.
  • PII filter (mandatory) strips email, hostname, internal IP ranges (RFC 1918 + RFC 6598 + 169.254/16 + fc00::/7) from free-text fields before queuing. Allowlist regex per field.
  • Anonymization default — operator name + org are blank-by- default; only included if operator explicitly types them in.
  • Local audit log permanent — every submission writes a read-only audit row the operator can export. LGPD/GDPR right-to- erasure honored via a "purge audit log" button.

5 submission types (Meraki-style placeholder examples):

  1. Bug report — what broke + what was expected + reproduction steps
  2. Feature request — what's missing + use-case
  3. Vendor request — vendor + SKU(s) the operator wants in the catalog
  4. Question — operator stuck; knows it's a learning-curve issue, not a bug
  5. Praise — what worked particularly well (rare but useful signal for product strategy)

HQ side (out of scope for the operator-facing implementation, documented here for completeness):

  • Submissions land in a triage inbox at HQ
  • Curated by humans
  • High-signal items become GitHub issues (linked back to submitter via opaque ID, not email)
  • LGPD/GDPR compliance: 90-day retention, encryption at rest, named DPO

Roadmap

PR Scope Lands
Feedback PR-1 Dashboard modal + 5 submission types + i18n next sprint
Feedback PR-2 Local SQLite queue + PII filter + audit log +1 sprint
Feedback PR-3 Cloner Function 3 (feedback-push) — already stubbed +1 sprint
Feedback PR-4 HQ endpoint + triage inbox UI (separate repo) TBD

Open questions

Tracked in source memo:

  1. HQ infrastructure — managed service vs self-hosted?
  2. Triage staff — engineering rotation vs dedicated PM?
  3. SLA — committed turnaround on triage? Public dashboard?
  4. GitHub policy — auto-create issues vs human-curated?
  5. Security review — annual pen-test of the HQ ingest endpoint?

Consequences

  • Positive: closes the feedback loop; operators feel heard; HQ gets product signal.
  • Negative: maintenance burden on HQ side; legal exposure on PII handling (mitigated by filter + anonymization).
  • Reversible: the operator-side modal can ship without the HQ side existing yet — submissions queue locally and flush when HQ is reachable.

References

  • Source memo: discuss_feedback_channel_2026_05_08.md
  • Cross-ref: project_cloner_platform_2026_05_08.md (Function 3)
  • Cross-ref: ADR 0015 (Help Center — adjacent surface)