@papi-ai/shared
Advanced tools
+26
-1
@@ -94,3 +94,28 @@ /** Valid task statuses on the cycle board. */ | ||
| }): boolean; | ||
| /** | ||
| * task-2776 (C335): sensitive-content blocklist for the PUBLIC changelog. | ||
| * | ||
| * The public /changelog re-derives its body from raw git commit subjects | ||
| * (CHANGELOG.md). Internal commit subjects routinely name owner/test-user | ||
| * accounts, internal funnel-metric confessions, security-incident internals, | ||
| * named team members, and internal comms channels — none of which should reach | ||
| * an unauthenticated external surface (AD-63: de-PAPI external-facing output). | ||
| * | ||
| * This is the CANONICAL list, imported by BOTH consumers so they cannot drift: | ||
| * - lib/changelog.ts (render chokepoint — covers page/json/xml AND every | ||
| * historical entry already committed to CHANGELOG.md) | ||
| * - packages/server/src/services/release.ts (write-time guard — keeps future | ||
| * CHANGELOG.md sections clean at the source) | ||
| * | ||
| * Patterns target INTERNAL markers specifically, not broad feature words — a | ||
| * legit user-facing line ("add Discord integration", "40% faster board load") | ||
| * must survive; only internally-scoped phrasing is dropped. | ||
| */ | ||
| declare const SENSITIVE_CHANGELOG_PATTERNS: readonly RegExp[]; | ||
| /** | ||
| * True when a changelog line exposes internal content that must not reach the | ||
| * public changelog. Applied per-line by both the render path and the write path. | ||
| */ | ||
| declare function isSensitiveChangelogLine(line: string): boolean; | ||
| export { CAPABILITY_KEYS, CAPABILITY_REGISTRY, type CapabilityDescriptor, type CapabilityKey, type CapabilityMap, type CapabilityStep, type EffortSize, RETIRED_DECISION_OUTCOMES, type ReviewStage, type ReviewVerdict, TASK_STATUSES, type TaskComplexity, type TaskPriority, type TaskStatus, type TaskType, VALID_TRANSITIONS, isCapabilityEnabled, isCapabilityKey, isLiveDecision, isValidStatus, isValidTransition, validateTransition }; | ||
| export { CAPABILITY_KEYS, CAPABILITY_REGISTRY, type CapabilityDescriptor, type CapabilityKey, type CapabilityMap, type CapabilityStep, type EffortSize, RETIRED_DECISION_OUTCOMES, type ReviewStage, type ReviewVerdict, SENSITIVE_CHANGELOG_PATTERNS, TASK_STATUSES, type TaskComplexity, type TaskPriority, type TaskStatus, type TaskType, VALID_TRANSITIONS, isCapabilityEnabled, isCapabilityKey, isLiveDecision, isSensitiveChangelogLine, isValidStatus, isValidTransition, validateTransition }; |
+40
-0
@@ -68,2 +68,40 @@ // src/index.ts | ||
| } | ||
| var SENSITIVE_CHANGELOG_PATTERNS = [ | ||
| // ── Test-user machinery ──────────────────────────────────────────────── | ||
| /@test\.papi\.dev/i, | ||
| /\btest[-\s]?users?\b/i, | ||
| /\b(cleanup|spawn)[-\s]?test[-\s]?users?\b/i, | ||
| /\bftue-[a-z0-9]/i, | ||
| // ── Named internal people / owner handles (not public-facing) ────────── | ||
| /\bcathalosullivan/i, | ||
| /\bencorekit\b/i, | ||
| /\bjess\b/i, | ||
| // ── Internal funnel-metric confessions ──────────────────────────────── | ||
| /\bcliff\b/i, | ||
| // "connect cliff" / "activation cliff" — internal only | ||
| /\bdeleted\b[^.]*\busers?\b/i, | ||
| // "91% deleted test users" | ||
| /\b\d{1,3}\s?%[^.]*\b(connect|activation|churn|retention|funnel|drop-?off|onboard)/i, | ||
| /\b(connect|activation|churn|retention|funnel|drop-?off)\b[^.]*\b\d{1,3}\s?%/i, | ||
| // ── Security / incident internals ────────────────────────────────────── | ||
| /\bvulnerabilit/i, | ||
| /\bCVE-\d/i, | ||
| /\bexploit\b/i, | ||
| /\bSUP-\d/i, | ||
| // internal support-incident IDs | ||
| /\bsecurity (incident|hole|leak|bug|flaw)\b/i, | ||
| /\bRLS\b/, | ||
| // row-level-security internals | ||
| /\bservice[-\s]?role\b/i, | ||
| /\banon (rls|socket)\b/i, | ||
| /\bauth(entication)? bypass\b/i, | ||
| /\btoken leak\b/i, | ||
| // ── Internal comms surfaces ──────────────────────────────────────────── | ||
| /#papi-[a-z-]+/i, | ||
| // internal Discord channel names | ||
| /\bdiscord (handle|@)/i | ||
| ]; | ||
| function isSensitiveChangelogLine(line) { | ||
| return SENSITIVE_CHANGELOG_PATTERNS.some((re) => re.test(line)); | ||
| } | ||
| export { | ||
@@ -73,2 +111,3 @@ CAPABILITY_KEYS, | ||
| RETIRED_DECISION_OUTCOMES, | ||
| SENSITIVE_CHANGELOG_PATTERNS, | ||
| TASK_STATUSES, | ||
@@ -79,2 +118,3 @@ VALID_TRANSITIONS, | ||
| isLiveDecision, | ||
| isSensitiveChangelogLine, | ||
| isValidStatus, | ||
@@ -81,0 +121,0 @@ isValidTransition, |
+1
-1
| { | ||
| "name": "@papi-ai/shared", | ||
| "version": "0.1.2", | ||
| "version": "0.1.3", | ||
| "description": "Shared types and business rules for PAPI — used by both MCP server and dashboard", | ||
@@ -5,0 +5,0 @@ "license": "Elastic-2.0", |
18510
21.26%240
37.14%