AI Slop Code RIsk Monitor

KeygraphHQ/shannon

Shannon is an AI pentester for web applications and APIs. It analyzes your source code, identifies attack vectors, and executes real exploits to prove vulnerabilities before they reach production.

4.8 Low pattern signal View on GitHub

Maintenance and Governance Review

This report summarizes scanner evidence for KeygraphHQ/shannon, a TypeScript project with 48,731 GitHub stars. SynthScan examined 69,726 lines of code across 310 source files, recording 238 pattern matches distributed across 7 syntactic categories. The legacy adjusted pattern signal is 4.8 (Low pattern signal); it is not an authorship estimate.

Use the findings to ask whether maintainers can explain intent, verify dependencies, simplify unnecessary scaffolding, and focus review effort. Risk Payload v1 adds ownership, supply-chain, over-engineering, and review-effort vectors when available. These are prompts for human verification, not probabilities, security findings, or measured maintenance costs.

4.8
Adjusted Signal
4.8
Raw Pattern Score
100%
Time Factor
2026-10-08
Last Push
48.7K
Stars
TypeScript
Language
69.7K
Lines of Code
310
Files
238
Pattern Hits
2026-10-12
Scan Date
0.05
HC Hit Rate

Risk Review · v3

Use each vector to guide manual verification of the underlying findings.

Cognitive Ownership Risk 17.0/100 · LOW

Can maintainers explain intent, assumptions, and trade-offs? 221 finding(s).

Hallucinated Dependency & Supply Chain Risk 5.1/100 · LOW

Are imports declared and package/API names verified? 17 finding(s).

Agent Over-Engineering Ratio 12.1/100 · LOW

Are wrappers, guards, and repeated structures necessary? 176 finding(s).

PR Review Velocity Impact 21.4/100 · LOW

Which changes need focused human review? 238 finding(s).

What These Metrics Mean

Adjusted Signal
Legacy pattern score normalized per 1,000 scanned lines and multiplied by the repository-level time factor. It is not an estimate of AI authorship.
Raw Pattern Score
Sum of severity- and context-weighted pattern findings before applying the time factor.
Time Factor
A coarse multiplier based on repository last-push metadata. It does not identify when individual code was written.
Pattern Hits
Count of configured pattern findings. Review each location and surrounding code before acting.
HC Hit Rate
High- and critical-severity findings per scanned file. Severity is a configured detector weight, not proof of a vulnerability or authorship.
Lines / Files
Scan coverage denominators used by the legacy normalized score.

Pattern-Signal History

This chart tracks the legacy adjusted pattern score across scan runs. Changes can reflect source changes, scan coverage, or detector/scoring versions; they do not measure AI adoption or prove that a team refactored code. Compare runs only when their scoring versions are compatible. The dashed line tracks the raw pattern-hit count.

Severity Breakdown

Groups findings by configured severity weight. Severity is not a confidence estimate, security rating, or proof that a package is missing. Verify imports against the project's manifests and inspect each finding in its local design context.

CRITICAL 0HIGH 16MEDIUM 9LOW 213

Directory Score Breakdown

This horizontal bar chart shows where configured pattern scores accumulate across directories. Treat the bars as locations to inspect, not as evidence of authorship or code quality. Use the file-level findings to decide whether a directory needs a focused ownership, dependency, complexity, or review check.

Pattern Findings

The scanner identified 238 distinct pattern matches across 7 syntactic categories. Each entry below represents a discrete location in the source code where the engine recorded a detector match to inspect in context. Expand any category row to inspect the individual file paths, line numbers, code snippets, and the lexical context (CODE, COMMENT, or STRING) in which each match was detected.

Reading the findings table: The Severity column indicates the configured finding weight (CRITICAL / HIGH / MEDIUM / LOW). The Context column identifies whether the match occurred inside executable code, an inline comment, or a string literal — legacy comment-context matches receive a ×1.5 score weight. The ⚡ bolt icon marks clustered matches: three or more patterns within a 10-line window, each receiving an additional ×1.5 density multiplier under the legacy scoring model.

Hyper-Verbose Identifiers176 hits · 179 pts
SeverityFileLineSnippetContext
LOWapps/cli/src/docker.ts195function readCurrentRetentionSeconds(): number | null {CODE
LOWapps/cli/src/docker.ts210function convergeNamespaceRetention(): void {CODE
LOWapps/cli/src/docker.ts291function ensureWorkerImageProtocol(image: string): void {CODE
LOWapps/cli/src/docker.ts582export function runningScanContainersChecked(CODE
LOWapps/cli/src/docker.ts621export function runningScanWorkspacesChecked(): CommandQueryResult<string[]> {CODE
LOWapps/cli/src/pending-workflow.ts40export function writePendingWorkflowIdentity(workspacePath: string, workflowId: string, taskQueue: string): void {CODE
LOWapps/cli/src/pending-workflow.ts73export function clearPendingWorkflowIdentity(workspacePath: string, taskQueue: string): void {CODE
LOWapps/cli/src/pending-workflow.ts83function isPendingWorkflowIdentity(CODE
LOWapps/cli/src/pending-workflow.ts113export function readPendingWorkflowIdentities(workspacePath: string): PendingWorkflowReadResult {CODE
LOWapps/cli/src/env.ts157function describeMissingCredential(providerId: string): string {CODE
LOWapps/cli/src/temporal-client.ts126export async function refreshWorkflowLifecycleConnection(): Promise<void> {CODE
LOWapps/cli/src/temporal-client.ts157export async function describeWorkflowLifecycle(workflowId: string): Promise<WorkflowLifecycleState> {CODE
LOWapps/cli/src/temporal-client.ts172export async function requestWorkflowCancellation(workflowId: string): Promise<'requested' | 'not-found'> {CODE
LOWapps/cli/src/temporal-client.ts183export async function requestWorkflowTermination(CODE
LOWapps/cli/src/config/resolver.ts235function assertNoCredentialConflict(toml: TOMLConfig): void {CODE
LOWapps/cli/src/scan/safe-fields.ts73function isProviderFailureCategory(value: unknown): value is string {CODE
LOWapps/cli/src/commands/logs.ts74export function appendCancellationFallback(logFile: string): void {CODE
LOWapps/cli/src/commands/setup.ts288function conflictingProviderPrefix(provider: string, value: string): string | undefined {CODE
LOWapps/cli/src/commands/start.ts230export function writeLaunchStateAtomically(CODE
LOWapps/cli/src/commands/start.ts741function printPreservedContainerHint(containerName: string): void {CODE
LOWapps/cli/src/commands/stop.ts289function verifiedContainerWorkflowId(CODE
LOWapps/cli/src/commands/stop.ts509function visibleWorkflowsForWorkspace(CODE
LOWapps/cli/src/commands/stop.ts680export async function stopVisibleWorkflowsUntilSettled(CODE
LOWapps/worker/src/temporal/workflows.ts222function hasCancellationInCauseChain(error: unknown): boolean {CODE
LOWapps/worker/src/temporal/workflows.ts226function applicationFailureInChain(error: unknown): ApplicationFailure | undefined {CODE
LOWapps/worker/src/temporal/workflows.ts242function shouldUseSingletonFallback(error: unknown): boolean {CODE
LOWapps/worker/src/temporal/workflows.ts273function reconciliationActivityOptions(CODE
LOWapps/worker/src/temporal/workflows.ts880 function projectCapellaWorkflowFailure(message: string, startedAt: number): void {CODE
LOWapps/worker/src/temporal/workflows.ts898 function projectCapellaInfrastructureFailure(startedAt: number): void {CODE
LOWapps/worker/src/temporal/workflows.ts1129 async function runMiscellaneousExploitLane(capella: Promise<CapellaSettlement>): Promise<void> {CODE
LOWapps/worker/src/temporal/reconcile-activity-types.ts48export function isAcceptedTaskFormationFallbackReason(value: unknown): value is TaskFormationFallbackReason {CODE
LOWapps/worker/src/temporal/reconcile-activity-types.ts223export function reconciliationClassDeadlineFrom(startedAtMs: number): number {CODE
LOWapps/worker/src/temporal/reconcile-activity-types.ts234export function resolveReconciliationActivityBudget(CODE
LOWapps/worker/src/temporal/reconcile-activities.ts251function chainContainsRealCancellation(error: unknown, signal: AbortSignal): boolean {CODE
LOWapps/worker/src/temporal/reconcile-activities.ts476export function createReconciliationActivityRegistry(CODE
LOWapps/worker/src/temporal/reconcile-activities.ts500 async function prepareClassReconciliation(input: PrepareClassReconciliationActivityInput) {CODE
LOWapps/worker/src/temporal/reconcile-activities.ts528 async function enrichClassSastObservations(input: EnrichClassSastObservationsActivityInput) {CODE
LOWapps/worker/src/temporal/reconcile-activities.ts577 async function materializeClassExploitTasks(input: MaterializeClassExploitTasksActivityInput) {CODE
LOWapps/worker/src/temporal/reconcile-activities.ts599 async function publishClassReconciliationOss(input: PublishClassReconciliationActivityInput) {CODE
LOWapps/worker/src/temporal/worker.ts233export function createProductionActivityRegistry(bindings: ProductionActivityBindings): Readonly<object> {CODE
LOWapps/worker/src/temporal/worker.ts405async function terminateExistingWorkflows(client: Client, workspaceName: string): Promise<string[]> {CODE
LOWapps/worker/src/temporal/activities.ts234function deterministicActivityFailure(error: unknown, failureType: string): ApplicationFailure {CODE
LOWapps/worker/src/temporal/activities.ts312async function rollbackInvalidReportDraft(input: ActivityInput, progress: ReportProgress): Promise<void> {CODE
LOWapps/worker/src/temporal/activities.ts540async function runVulnAgentWithCollector(CODE
LOWapps/worker/src/temporal/activities.ts622async function runExploitAgentWithCollector(CODE
LOWapps/worker/src/temporal/activities.ts691export async function runMiscellaneousExploitAgent(input: ActivityInput): Promise<AgentMetrics> {CODE
LOWapps/worker/src/temporal/activities.ts885export async function runCyberAccessVerification(_input: ActivityInput): Promise<{ gated: boolean }> {CODE
LOWapps/worker/src/temporal/activities.ts952export async function runAuthenticationValidation(input: ActivityInput): Promise<AgentMetrics | null> {CODE
LOWapps/worker/src/temporal/activities.ts1070export async function syncPlaywrightStealthConfig(input: ActivityInput): Promise<void> {CODE
LOWapps/worker/src/temporal/activities.ts1110export async function initializeDurableScanState(CODE
LOWapps/worker/src/temporal/activities.ts1125export async function persistMiscellaneousOutcome(CODE
LOWapps/worker/src/temporal/activities.ts1275export async function persistCanonicalReportProgress(CODE
LOWapps/worker/src/temporal/activities.ts1379export async function persistFinalizedReportProgress(CODE
LOWapps/worker/src/temporal/activities.ts1753export async function persistOrValidateRunScope(CODE
LOWapps/worker/src/types/errors.ts64export function isProviderFailureCategory(value: unknown): value is ProviderFailureCategory {CODE
LOWapps/worker/src/types/run-state.ts386function isBoundedPartialReasonCount(value: unknown): value is number {CODE
LOWapps/worker/src/types/run-state.ts472function hasConflictingClassReasons(reasons: readonly PartialReason[]): boolean {CODE
LOWapps/worker/src/types/run-state.ts486export function isOrderedPartialReasonSet(value: unknown): value is readonly PartialReason[] {CODE
LOWapps/worker/src/types/run-state.ts641function renderIncompleteResearchReduction(CODE
LOWapps/worker/src/types/run-state.ts695export function partialReasonFromReduction(reduction: AgenticSastReduction): PartialReason {CODE
116 more matches not shown…
Magic Placeholder Names14 hits · 70 pts
SeverityFileLineSnippetContext
HIGHllms-full.txt453ANTHROPIC_API_KEY=your-api-keyCODE
HIGHllms-full.txt459export ANTHROPIC_API_KEY="your-api-key"CODE
HIGHllms-full.txt820export SHANNON_AI_API_KEY=your-api-key # the provider's key — or the gateway's when a base URL is seCODE
HIGHllms-full.txt954 "apiKey": "YOUR_API_KEY",CODE
HIGHllms-full.txt996export SHANNON_AI_API_KEY=your-api-keyCODE
HIGHllms-full.txt1000Leave `YOUR_API_KEY` exactly as it is. Shannon sends the credential from your environment, and that takes precedence oveCODE
HIGHllms-full.txt1139api_key = "your-api-key"CODE
HIGHdocs/ai-providers.md31export SHANNON_AI_API_KEY=your-api-key # the provider's key — or the gateway's when a base URL is seCODE
HIGHdocs/ai-providers.md165 "apiKey": "YOUR_API_KEY",CODE
HIGHdocs/ai-providers.md207export SHANNON_AI_API_KEY=your-api-keyCODE
HIGHdocs/ai-providers.md211Leave `YOUR_API_KEY` exactly as it is. Shannon sends the credential from your environment, and that takes precedence oveCODE
HIGHdocs/ai-providers.md350api_key = "your-api-key"CODE
HIGHdocs/development.md35ANTHROPIC_API_KEY=your-api-keyCODE
HIGHdocs/development.md41export ANTHROPIC_API_KEY="your-api-key"CODE
Structural Annotation Overuse27 hits · 40 pts
SeverityFileLineSnippetContext
LOW.claude/commands/debug.md7## Step 1: Capture Error ContextCOMMENT
LOW.claude/commands/debug.md20## Step 2: Check Relevant LogsCOMMENT
LOW.claude/commands/debug.md35## Step 3: Trace the Call PathCOMMENT
LOW.claude/commands/debug.md50## Step 4: Identify Root CauseCOMMENT
LOW.claude/commands/debug.md90## Step 5: Apply Fix with Retry LimitCOMMENT
LOW.claude/commands/debug.md99## Step 6: Validate the FixCOMMENT
LOW.claude/commands/review.md7## Step 1: Gather ChangesCOMMENT
LOW.claude/commands/review.md14## Step 2: Check Shannon-Specific PatternsCOMMENT
LOW.claude/commands/review.md66## Step 3: TypeScript SafetyCOMMENT
LOW.claude/commands/review.md83## Step 4: Security ReviewCOMMENT
LOW.claude/commands/review.md95## Step 5: Common Mistakes to AvoidCOMMENT
LOW.claude/commands/review.md112## Step 6: Provide FeedbackCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-authz.txt7### Step 1: Test Browser IsolationCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-authz.txt23### Step 2: Create Required DeliverableCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-authz.txt31### Step 3: Verify Session IsolationCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-ssrf.txt7### Step 1: Test Browser IsolationCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-ssrf.txt23### Step 2: Create Required DeliverableCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-ssrf.txt31### Step 3: Verify Session IsolationCOMMENT
LOW…/worker/prompts/pipeline-testing/exploit-injection.txt7### Step 1: Test Browser IsolationCOMMENT
LOW…/worker/prompts/pipeline-testing/exploit-injection.txt23### Step 2: Create Required DeliverableCOMMENT
LOW…/worker/prompts/pipeline-testing/exploit-injection.txt31### Step 3: Verify Session IsolationCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-xss.txt7### Step 1: Test Browser IsolationCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-xss.txt23### Step 2: Create Required DeliverableCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-xss.txt31### Step 3: Verify Session IsolationCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-auth.txt7### Step 1: Test Browser IsolationCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-auth.txt23### Step 2: Create Required DeliverableCOMMENT
LOWapps/worker/prompts/pipeline-testing/exploit-auth.txt31### Step 3: Verify Session IsolationCOMMENT
Modern AI Meta-Vocabulary9 hits · 23 pts
SeverityFileLineSnippetContext
MEDIUMREADME.md255No source code? Use the [Blackbox Pentester](https://keygraph.io/agentic-blackbox-pentester).CODE
MEDIUMllms-full.txt265No source code? Use the [Blackbox Pentester](https://keygraph.io/agentic-blackbox-pentester).CODE
MEDIUMllms-full.txt1386No source code? Use the [Blackbox Pentester](https://keygraph.io/agentic-blackbox-pentester).CODE
MEDIUMdocs/keygraph-platform.md11No source code? Use the [Blackbox Pentester](https://keygraph.io/agentic-blackbox-pentester).CODE
MEDIUMapps/cli/src/scan/status-json.ts92 // Present only when agentic SAST actually ran; a disabled scan omits the key entirely.COMMENT
MEDIUMapps/cli/src/scan/render.ts276 // The safe message names what degraded; these three name the agentic-SAST failureCOMMENT
MEDIUMapps/worker/src/session-manager.ts107 // or agentic SAST). It has no analysis-phase counterpart: there is no 'miscellaneous-vuln'COMMENT
MEDIUMapps/worker/src/temporal/worker.ts645 // agentic-SAST failure behind it, under the same labels every other surface uses.COMMENT
MEDIUMapps/worker/src/audit/metrics-tracker.ts900 // Operational work (agentic SAST, reconciliation) runs concurrently with the agent phases and isCOMMENT
Synthetic Comment Markers2 hits · 10 pts
SeverityFileLineSnippetContext
HIGHllms-full.txt11073. Select **OAuth Token** and enter the token generated by Claude Code.CODE
HIGHdocs/ai-providers.md3183. Select **OAuth Token** and enter the token generated by Claude Code.CODE
Over-Commented Block7 hits · 7 pts
SeverityFileLineSnippetContext
LOWllms-full.txt681 # code_path values are repo-relative file paths or globs.COMMENT
LOWdocs/configuration.md41```yamlCOMMENT
LOWapps/worker/configs/example-config.yaml1# Example configuration file for pentest-agentCOMMENT
LOWapps/worker/configs/example-config.yaml21# rules_of_engagement: |COMMENT
LOWapps/worker/configs/example-config.yaml101COMMENT
LOWapps/worker/src/session-manager.ts1// Copyright (C) 2026 Keygraph, Inc.COMMENT
LOWapps/worker/src/services/error-handling.ts21// status/headers mirrors pi's request-layer policy, and every other (flattened) failureCOMMENT
Fake / Example Data3 hits · 3 pts
SeverityFileLineSnippetContext
LOWsample-reports/shannon-report-crapi.md57 -d '{"email": "admin@example.com", "password": "Admin!123"}'CODE
LOWsample-reports/shannon-report-crapi.md139 -d '{"email": "admin@example.com", "password": "Admin!123"}'CODE
LOWsample-reports/shannon-report-crapi.md242 - Payload: `{"sub": "admin@example.com", "iat": 1758655244, "exp": 1759260044, "role": "admin"}`CODE