Skip to content

feat: insta feedback — report InstaCloud-side hurdles - #95

Merged
Fermionic-Lyu merged 1 commit into
mainfrom
feat/feedback
Aug 18, 2026
Merged

feat: insta feedback — report InstaCloud-side hurdles#95
Fermionic-Lyu merged 1 commit into
mainfrom
feat/feedback

Conversation

@Fermionic-Lyu

@Fermionic-Lyu Fermionic-Lyu commented Aug 18, 2026

Copy link
Copy Markdown
Member

What

New top-level insta feedback command: agents (and humans) report an InstaCloud-side hurdle — bug / feature-request / friction — to the team, then continue their task. Modeled on insforge feedback (not copied): same dual-audience UX, InstaCloud-native taxonomy and transport.

Backend (dogfood)

Posts to the InstaCloud Agent Feedback project — InstaCloud running on InstaCloud (postgres db + compute api, ingest service versioned in InsForge/insta-feedback). Deliberately not the control plane: feedback must work logged-out, unlinked, from oss, and during control-plane outages. Endpoint + public ingest token are hardcoded in source (a build-time secret silently no-ops in local/fork builds); INSTA_FEEDBACK_URL/INSTA_FEEDBACK_TOKEN override for tests/rotation.

Design decisions

  • TTY → clack wizard; non-TTY/--json → self-teaching enum errors. An agent can never hang on a prompt (feedback.ts feedback(), checked at commit HEAD).
  • Transport/server failures warn + exit 0; validation errors exit 1. An agent can fix its flags, it cannot fix a down backend — feedback never fails the user's actual task.
  • Local redact-then-truncate (src/redact.ts): JWTs, bearer/keys, emails, URL creds, home dirs, public IPv4. insta_ key pattern requires a ≥24-char tail so MCP tool names (insta_feedback, insta_storage_download_url) survive — caught live in e2e. Server re-scrubs.
  • Server-side-only anti-abuse: 20/h per-IP (salted hash, advisory-lock-serialized) + ISO-week dedup folding (duplicate_count++, returns the existing id as status: duplicate).
  • Auto context: project/org/branch link, cloud|oss target, CLI/node/OS versions.

Verified live (prod backend)

  • submit → received + id; same-title resubmit → duplicate, same id; row inspected in DB with redaction applied
  • 21st admission in the hour → 429 (probe rows cleaned after)
  • non-TTY missing flag → exit 1 with enum list; npm run typecheck && npm test green (306)

Companion PRs: insta-mcp (insta_feedback tool) and insta-skills (agent-facing docs — merge after this ships).

🤖 Generated with Claude Code


Summary by cubic

Adds a new top-level insta feedback command to report InstaCloud-side hurdles. Reports go to a dogfooded feedback service instead of the control plane, so it works logged-out and during control‑plane outages.

  • Wire-up: new src/commands/feedback.ts, src/redact.ts, CLI registration in src/index.ts, README entry, and tests in test/feedback.test.ts.
  • Transport: POST to a fixed endpoint with a public ingest token; 10s timeout; no retries. Override with INSTA_FEEDBACK_URL and INSTA_FEEDBACK_TOKEN.
  • UX: TTY runs a short @clack/prompts wizard for missing fields; non‑TTY/--json requires enums and shows self-teaching errors. Required: --type, --component, --title, and one of --detail or --file.
  • Behavior: validation errors exit 1; transport/server failures warn and exit 0. Maps server “duplicate” to a benign result.
  • Privacy: local redact‑then‑truncate of free-text (JWTs, bearer keys, insta_ tokens with ≥24‑char tails, emails, URL creds, home dirs, public IPv4). Server also re-scrubs.
  • Context: attaches project/org/branch link, cloud|oss target, and CLI/Node/OS versions.

Rollout and migration

  • No breaking changes to existing commands.
  • Automation should pass the required flags and use --json for machine-readable output.
  • For tests or emergency rotation, set INSTA_FEEDBACK_URL and INSTA_FEEDBACK_TOKEN.

Written for commit 6b96d26. Summary will update on new commits.

Review in cubic

New top-level command posting to the dogfooded feedback backend (project
'InstaCloud Agent Feedback', InsForge/insta-feedback service), not the
control plane — reports must survive control-plane outages and work
logged-out/unlinked/oss.

- TTY: clack wizard for missing required fields; non-TTY/--json: loud
  self-teaching enum errors (agents must never hang on a prompt)
- local redact-then-truncate (src/redact.ts) before anything leaves the
  machine; server re-scrubs
- transport/server failures warn + exit 0 (feedback never fails the
  user's task); validation errors exit 1 (agent can fix flags)
- auto context: project/org/branch link, cloud|oss target, CLI/node/OS
  versions

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@Fermionic-Lyu
Fermionic-Lyu enabled auto-merge (squash) August 18, 2026 19:23

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary

Adds a self-contained insta feedback command that reports InstaCloud-side hurdles to a dogfooded ingest backend, with local PII redaction, agent-safe non-blocking behavior, and solid unit coverage — no blocking issues found.

Requirements context

No matching spec/plan found — insta-cli has no /docs/superpowers/ or docs/specs/ directory. Assessed against the PR description, the referenced insforge feedback model, and existing repo conventions (env.ts, config.ts, guard/onError, the test/*.test.ts pattern).

Findings

Critical

(none)

Suggestion

  • Functionality — --json validation errors are emitted as plaintext, not JSON. src/commands/feedback.ts:200-212 — when non-interactive with a bad/missing flag, buildPayload throws and unwinds through guardonErrordie, which writes a bare text line and exits 1. That's the intended self-teaching path, but a caller that passed --json (agents especially) gets a non-JSON stderr line while every success/transport path returns JSON. Consider catching validation failure in the opts.json branch and emitting {status:'error', submitted:false, error} for a uniform machine-readable contract. Low blast radius; the enum message is still present either way.
  • Functionality — --file reads the whole file into memory before truncation. src/commands/feedback.ts:150-156readFileSync(opts.file,'utf8') loads the entire file, then clean() truncates to 4000 chars. Pointing at a huge or binary file allocates it all up front and could dump binary garbage into detail. User-initiated and rare, but a size guard (or is-this-text check) before the redact/truncate pass would harden it.
  • Security — public-IPv4 redaction can over-scrub diagnostic text. src/redact.ts:33-45 — the IPV4 pattern rewrites any public 4-octet dotted number to [REDACTED_IP], so 4-part version/build strings or numeric IDs in error output get mangled. This is the same false-positive/diagnostic-value tradeoff the file cites for skipping IPv6, applied in the opposite direction; worth a comment acknowledging the asymmetry, or narrowing with surrounding-context anchors.

Information

  • Software engineering — the interactive promptMissing wizard is untested. src/commands/feedback.ts:96-140 — the pure logic (buildPayload, submit, feedback, redaction) is well covered in test/feedback.test.ts, and the clack TTY path is genuinely awkward to unit-test, so this is acceptable; noting the gap only.
  • Security — hardcoded endpoint + public ingest token are intentional. src/commands/feedback.ts:36-41 — documented as public-by-design (deflects drive-by scanners; real abuse control is server-side per-IP rate limit + weekly dedup), overridable via INSTA_FEEDBACK_URL/INSTA_FEEDBACK_TOKEN. No secret is leaked that wasn't meant to ship. Local redaction covers URL creds, JWTs, bearer/insta_/third-party keys, generic key=value assignments, emails, home dirs, and public IPv4, with a documented server-side re-scrub as the backstop — a bare token=… not in the assignment allowlist could slip past locally but is caught server-side.
  • Performance — no concerns. One POST with a 10s AbortSignal.timeout and zero retries; transport/server failures downgrade to a warning and exit 0. No loops, N+1, or hot-path work. AbortSignal.timeout, global fetch, and TimeoutError detection are all valid on the declared node >=18.
  • Software engineering — conventions honored. .js ESM imports, guard(...) wrapping, info/printJson from util.ts, envForApiUrl reused for the cloud|oss target, and resolveCliVersion mirroring index.ts's version resolution. The command is registered once and the README table row matches the scope statement.

Verdict

approved (informational — human approval still required via the approve flow). Zero Critical findings; the Suggestions are non-blocking polish. A well-structured, agent-aware feature with redaction and failure semantics that match its stated design.

@jwfing jwfing left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM - approved.

@Fermionic-Lyu
Fermionic-Lyu merged commit 248ede4 into main Aug 18, 2026
2 checks passed
Fermionic-Lyu added a commit that referenced this pull request Aug 18, 2026
- --json validation errors now emit {status:'error', submitted:false,
  error} on stdout (exit still 1) — uniform machine-readable contract
  with the success and transport-failure shapes
- --file: reject >256KB before reading (detail caps at 4000 chars; a
  huge file is a wrong path or an archive) and reject binary content
  (NUL check) instead of truncating garbage
- redact.ts: document the accepted IPv4 over-scrub asymmetry

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Fermionic-Lyu added a commit that referenced this pull request Aug 18, 2026
Ships insta feedback (#95, #96, #98).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants