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 (sibling — Sage/Clara intake + classification), SPEC-113 v0.3 ($PRISM_ROOT / $PROJECT_ROOT boundary), ADR #58 (recall-class split), SPEC-094 (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
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:
{
"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:
{
"approved": true,
"approved_by": "Frank|operator identity",
"approved_at": "ISO-8601",
"review_surface": "terminal|dashboard|cli",
"notes": "optional"
}
redaction_report minimum shape:
{
"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:
- Summary
- Severity / scope / kind
- Environment snapshot, redacted
- Symptom record, redacted
- Local artifact refs, redacted/stable ids only
- Reproduction steps if supplied and approved
- Clara classification note
- Redaction report summary
- 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.
Last modified on May 18, 2026