fix: restore dead severity signal, per-portal resilience, PII audit correctness#21
Merged
Conversation
The severity formula's thread-depth term was dead in production: thread bodies were never fetched, so thread_count was always 0 and min(0*10, 50) contributed nothing. Use the list API's threads count field instead (no extra API calls) and treat 0/missing as the baseline 1. Also: - Clamp recency so an unparseable created_at can't produce NaN scores and future-dated tickets can't pin severity to 100 - Strip PII-redaction placeholders before n-gram tokenization so 'email redacted' can't surface as an emerging theme - Delete the unreachable thread-body fetch path (includeThreads was never set by any caller; last present at d5f985f) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- One failing ProductLift portal no longer drops every portal's data; failures surface as named-portal warnings in the response - Total fetch failure (all sources) returns isError instead of an empty analysis that reads as success, and is never cached - Replace the module-global PII category log with an explicit per-request sink; concurrent tool calls no longer interleave audit metadata - get_feature_requests reports pii_scrubbing_applied and pii_categories_redacted, and stops sending commenter names (role only) - A malformed PRODUCTLIFT_PORTALS degrades to zero portals with the error surfaced in tool descriptions instead of killing the server - Label feature requests with their actual source portal - Guard themes.config.json loading with an actionable error - Scrub upstream error text in warnings; collapse whitespace in quotes - preview_only now describes exactly what is fetched and sent Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 2, 2026
Transitive dep of @modelcontextprotocol/sdk; npm audit flagged the 4.12.x line high (GHSA-xrhx-7g5j-rcj5 and related). Lockfile-only. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This was referenced Jul 2, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes from an adversarially verified quality audit. Two commits: scoring correctness, then resilience and PII handling. Every finding below was confirmed against the code (and the MCP SDK source for the concurrency one) before fixing.
Scoring correctness (commit 1)
thread_countwas always 0 andmin(0 * 10, 50)contributed nothing, while the README and methodology present thread depth as a severity input. The count now comes from the HelpScout list API'sthreadsfield, which costs no extra API calls. Note the semantics: it counts all thread types (agent replies, notes), and the curve saturates at 5 threads. Curve tuning is a follow-up.|| 1instead of?? 1), pinned by a regression test.created_atcan no longer produce NaN priority scores, and future-dated tickets no longer pin severity to the cap.[EMAIL REDACTED]are stripped before n-gram detection, so "email redacted" can't show up as an emerging theme (it previously could, verified empirically).includeThreads; raw thread bodies stay excluded by design pending a privacy review. Last present at d5f985f.Resilience and PII (commit 2)
isErrorwith the warnings instead of an empty analysis that reads as success, and failed fetches are never cached.get_feature_requestsnow reportspii_scrubbing_applied/pii_categories_redactedlike the other tools, and stops sending commenter names (role only). Names were the one identity field that bypassed the "all text is scrubbed" guarantee.PRODUCTLIFT_PORTALSno longer kills the whole server at startup; it degrades to zero portals and surfaces the config error in tool descriptions andlist_sources.preview_onlynow describes exactly what is fetched and sent. It previously claimed comment text and message bodies were sent; the analysis path fetches neither.Behavior changes to be aware of
get_feature_requestsoutput: comment objects lose theauthorfield; responses gain the twopii_*fields and optionalwarnings.Verification
npm run buildandnpm testgreen after each commit (40 tests, 6 new).synthesize_feedback(552 signals, all scores finite, severity term live, no placeholder n-grams),generate_product_plan preview_only,get_feature_requests(correct portal labels, no author fields, PII fields present),list_sources.🤖 Generated with Claude Code