feat: insta feedback — report InstaCloud-side hurdles - #95
Conversation
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>
jwfing
left a comment
There was a problem hiding this comment.
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 —
--jsonvalidation errors are emitted as plaintext, not JSON.src/commands/feedback.ts:200-212— when non-interactive with a bad/missing flag,buildPayloadthrows and unwinds throughguard→onError→die, 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 theopts.jsonbranch 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 —
--filereads the whole file into memory before truncation.src/commands/feedback.ts:150-156—readFileSync(opts.file,'utf8')loads the entire file, thenclean()truncates to 4000 chars. Pointing at a huge or binary file allocates it all up front and could dump binary garbage intodetail. User-initiated and rare, but a size guard (oris-this-textcheck) before the redact/truncate pass would harden it. - Security — public-IPv4 redaction can over-scrub diagnostic text.
src/redact.ts:33-45— theIPV4pattern 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
promptMissingwizard is untested.src/commands/feedback.ts:96-140— the pure logic (buildPayload,submit,feedback, redaction) is well covered intest/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 viaINSTA_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, generickey=valueassignments, emails, home dirs, and public IPv4, with a documented server-side re-scrub as the backstop — a baretoken=…not in the assignment allowlist could slip past locally but is caught server-side. - Performance — no concerns. One
POSTwith a 10sAbortSignal.timeoutand zero retries; transport/server failures downgrade to a warning and exit 0. No loops, N+1, or hot-path work.AbortSignal.timeout, globalfetch, andTimeoutErrordetection are all valid on the declarednode >=18. - Software engineering — conventions honored.
.jsESM imports,guard(...)wrapping,info/printJsonfromutil.ts,envForApiUrlreused for thecloud|osstarget, andresolveCliVersionmirroringindex.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.
- --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>
What
New top-level
insta feedbackcommand: agents (and humans) report an InstaCloud-side hurdle — bug / feature-request / friction — to the team, then continue their task. Modeled oninsforge 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+ computeapi, 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_TOKENoverride for tests/rotation.Design decisions
--json→ self-teaching enum errors. An agent can never hang on a prompt (feedback.tsfeedback(), checked at commit HEAD).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.duplicate_count++, returns the existing id asstatus: duplicate).cloud|osstarget, CLI/node/OS versions.Verified live (prod backend)
received+ id; same-title resubmit →duplicate, same id; row inspected in DB with redaction appliednpm run typecheck && npm testgreen (306)Companion PRs: insta-mcp (
insta_feedbacktool) and insta-skills (agent-facing docs — merge after this ships).🤖 Generated with Claude Code
Summary by cubic
Adds a new top-level
insta feedbackcommand 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.src/commands/feedback.ts,src/redact.ts, CLI registration insrc/index.ts, README entry, and tests intest/feedback.test.ts.INSTA_FEEDBACK_URLandINSTA_FEEDBACK_TOKEN.@clack/promptswizard for missing fields; non‑TTY/--jsonrequires enums and shows self-teaching errors. Required:--type,--component,--title, and one of--detailor--file.insta_tokens with ≥24‑char tails, emails, URL creds, home dirs, public IPv4). Server also re-scrubs.cloud|osstarget, and CLI/Node/OS versions.Rollout and migration
--jsonfor machine-readable output.INSTA_FEEDBACK_URLandINSTA_FEEDBACK_TOKEN.Written for commit 6b96d26. Summary will update on new commits.