> ## Documentation Index
> Fetch the complete documentation index at: https://prism.ntecdev.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# SPEC-115: prism_phone_home and ET GitHub Issue Transport

> Controlled Prism-product phone-home channel — prism_phone_home verb + ET gitapp helper transporting approved redacted incident packets to the private invite-only FrankTewksbury/Prism repo via gh CLI

# SPEC-115 v0.1 — prism\_phone\_home and ET GitHub Issue Transport

**Status:** accepted (Donna ratified under delegated PO authority 2026-05-13 17:02Z).
**Owner / Author:** Texi (architecture), Donna (PO + backend/ET implementation).
**Implementation lanes:** Donna (backend/ET + prompt/rubric integration with Clara, Candi review), Lafonda (server1 deployment), Cherry + Donna (smoke validation with Frank verifying first issue appearance).
**Related:** [SPEC-114 v0.1](/specs/spec-114-v0-1-sage-and-clara-customer-care-incident-personas) (sibling — Sage/Clara intake + classification), [SPEC-113 v0.3](/specs/spec-113-v0-3-bootstrap-path-resolution-and-scaffold-completeness) (`$PRISM_ROOT` / `$PROJECT_ROOT` boundary), ADR #58 (recall-class split), [SPEC-094](/specs/spec-094-v0-5-memorules-delta) (local auto-memory deprecation), Plan #19 v0.1.

## Origin

Plan #19 v0.1, Frank greenlight 2026-05-13 16:00Z. Donna assigned architecture drafting to Texi via signal `146d19b5`.

## Purpose

Add a controlled Prism-product phone-home channel before Prism Cloud exists.

v0.1 introduces:

* `prism_phone_home` verb.
* **ET** gitapp\_helper service/module.
* GitHub issue transport through `gh` CLI to the private invite-only `FrankTewksbury/Prism` repository.

v0.2 will replace or augment `gh` CLI transport with a GitHub App using Prism Bot identity. v0.2 is a follow-up, not part of v0.1 acceptance.

## Scope Split

Customer-internal incidents stay local in the customer project lifecycle. ET phones home only for Prism-product issues.

Clara owns classification under SPEC-114:

* `Prism-product`: eligible for phone-home after redaction and operator review.
* `customer-internal`: never phone-home.
* `mixed`: phone-home only the redacted Prism-product subset after operator review.

ET does not classify incident scope. ET only validates the packet and transports an approved phone-home request.

## Anchors

* SPEC-114: Sage/Clara intake and incident classification.
* SPEC-113: `$PRISM_ROOT` owns Prism product; `$PROJECT_ROOT` is customer mutable space. Phone-home does not mutate `$PROJECT_ROOT` outside local Prism accounting writes.
* ADR #58: recall-class split. Phone-home payload construction must not pull `intel/%` unless explicitly requested and justified.
* SPEC-094: no local auto-memory. Phone-home packets are built from Prism verbs, explicit reporter input, and approved local incident artifacts.

## Verb Contract

```python theme={null}
prism_phone_home(
    pid: str,
    incident_id: str,
    severity: Literal['P0','P1','P2','P3'],
    scope: Literal['Prism-product','mixed'],
    kind: Literal['incident','enhancement','recommendation'],
    title: str,
    body_markdown: str,
    labels: list[str] | None = None,
    local_artifact_refs: list[str] | None = None,
    redaction_report: dict | None = None,
    operator_review: dict,
    idempotency_key: str | None = None,
    dry_run: bool = False,
) -> dict
```

Required invariants:

* `scope='customer-internal'` is rejected.
* `operator_review.approved == true` is required unless `dry_run=true`.
* `redaction_report.status == 'passed'` is required unless `dry_run=true`.
* `body_markdown` must be the reviewed/redacted body, not raw incident input.
* `idempotency_key` defaults to a stable hash of `pid + incident_id + title + body_sha256`.

Return shape:

```json theme={null}
{
  "status": "created" | "duplicate" | "dry_run" | "failed",
  "transport": "gh_cli",
  "repo": "FrankTewksbury/Prism",
  "issue_url": "https://github.com/FrankTewksbury/Prism/issues/N",
  "issue_number": 123,
  "idempotency_key": "...",
  "local_artifact_refs": ["..."],
  "redaction_report": {...},
  "error": null
}
```

## ET Service Contract

ET is a backend/helper service, not a customer-care persona in v0.1.

Responsibilities:

* Validate `prism_phone_home` invariants.
* Apply idempotency/dedupe before transport.
* Render GitHub issue title/body/labels from the approved packet.
* Execute `gh issue create` against `FrankTewksbury/Prism` for v0.1.
* Return issue URL/number and write local cross-link metadata through Prism storage.
* Fail loudly with structured failure modes.

Non-responsibilities:

* ET does not classify scope.
* ET does not redact raw content independently of Clara/operator review, though it may reject obvious secrets as defense in depth.
* ET does not read customer project content.
* ET does not bypass operator review.

## v0.1 Transport: gh CLI

Transport target:

* Repo: `FrankTewksbury/Prism`
* Visibility: private invite-only.
* Auth: local operator/user `gh` CLI auth.

Preflight:

* `gh --version` is available.
* `gh auth status` succeeds.
* Authenticated account has access to `FrankTewksbury/Prism`.
* `gh repo view FrankTewksbury/Prism` succeeds.

Create command shape:

* `gh issue create --repo FrankTewksbury/Prism --title <title> --body-file <temp-reviewed-body> --label <labels...>`
* Temporary body file must contain only reviewed/redacted content and be deleted after use.
* No raw incident packet is written to disk except the reviewed temp body needed by `gh`, and only for the duration of the transport call.

Failure mode for missing invite/access:

* `phone_home_repo_access_denied`

## v0.2 Transport Follow-Up

v0.2 will add GitHub App transport:

* Prism Bot identity.
* Installation token flow.
* No dependency on local operator `gh` auth.
* Better audit of app identity and customer consent.

v0.2 must preserve the v0.1 redaction and operator-review-before-send invariants.

## Redaction and Review Contract

Before `prism_phone_home` creates an issue:

* PII must be removed or explicitly approved.
* Customer-content snippets must be removed unless necessary and explicitly approved.
* Secrets/tokens/keys must be removed.
* Hostnames, usernames, paths, repo names, tenant names, and project names are reviewed and either redacted or approved.
* The operator sees the final issue title/body/labels before send.

`operator_review` minimum shape:

```json theme={null}
{
  "approved": true,
  "approved_by": "Frank|operator identity",
  "approved_at": "ISO-8601",
  "review_surface": "terminal|dashboard|cli",
  "notes": "optional"
}
```

`redaction_report` minimum shape:

```json theme={null}
{
  "status": "passed",
  "redacted_fields": ["paths", "tokens", "customer_content"],
  "retained_sensitive_fields": [],
  "body_sha256": "sha256 of reviewed body"
}
```

If sensitive fields are retained, the operator review must explicitly acknowledge them.

## GitHub Issue Shape

Labels:

* `phone-home`
* `customer-care`
* `severity:P0|P1|P2|P3`
* `kind:incident|enhancement|recommendation`
* `scope:prism-product|mixed`
* Optional component labels such as `signals`, `bootstrap`, `install`, `memory`, `dashboard`, `scheduler`, `docs`.

Body sections:

1. Summary
2. Severity / scope / kind
3. Environment snapshot, redacted
4. Symptom record, redacted
5. Local artifact refs, redacted/stable ids only
6. Reproduction steps if supplied and approved
7. Clara classification note
8. Redaction report summary
9. Local incident cross-link placeholder or id

The issue body must not contain raw customer project content by default.

## Local Cross-Linking

On success, ET records the GitHub URL locally so future local incident work can navigate both directions:

* Update or append to local `prism_postmortem` / incident artifact when supported.
* Add `prism_journal` entry with issue URL and idempotency key.
* Signal Clara with the `issue_url`, `issue_number`, and local refs.

If GitHub issue creation succeeds but local cross-linking fails, return `phone_home_crosslink_failed` and include the issue URL so Clara can repair local accounting.

## Idempotency

ET must avoid duplicate issues for the same approved incident packet.

Minimum v0.1 behavior:

* Compute/store idempotency key from incident id and reviewed body hash.
* If the same key is submitted again, return prior issue URL when available.
* If local dedupe storage is unavailable, include idempotency marker in issue body and search recent open issues before create where feasible.

## Failure Modes

* `phone_home_repo_access_denied`: local `gh` account cannot access `FrankTewksbury/Prism`.
* `phone_home_transport_unavailable`: `gh` CLI missing or unusable.
* `phone_home_auth_required`: `gh auth status` fails.
* `phone_home_scope_rejected`: request is customer-internal or scope not eligible.
* `phone_home_redaction_required`: redaction report missing or not passed.
* `phone_home_operator_review_required`: operator approval missing.
* `phone_home_sensitive_retention_unapproved`: sensitive fields retained without explicit operator acknowledgement.
* `phone_home_duplicate`: idempotency key already has an issue.
* `phone_home_issue_create_failed`: GitHub issue creation failed after preflight passed.
* `phone_home_crosslink_failed`: GitHub issue exists but local cross-link write failed.

## Acceptance Criteria

* Dry-run returns rendered issue title/body/labels without calling GitHub.
* Customer-internal scope is rejected.
* Missing operator review is rejected.
* Missing/pending redaction report is rejected.
* Missing repo access returns `phone_home_repo_access_denied`.
* Successful v0.1 call creates a private GitHub issue in `FrankTewksbury/Prism` through `gh` CLI.
* Successful call records local cross-link and signals Clara with issue URL.
* Re-running the same approved packet returns duplicate/prior issue instead of creating a new one.
* Temp files contain only reviewed content and are cleaned up.

## Ownership

* Architecture/spec: Texi.
* PO/ratification: Donna.
* Backend/ET implementation: Donna.
* Prompt/rubric integration with Clara: Donna + Candi review.
* Server1 deployment: Lafonda.
* Smoke validation: Cherry + Donna, with Frank verifying first issue appearance.
