AI Slop Code Risk Monitor

Fission-AI/OpenSpec

SlopCodeMonitor badge for Fission-AI/OpenSpec Adjusted legacy signal; badge bands: 25 / 50 / 75 (different from dashboard bands).

Spec-driven development (SDD) for AI coding assistants.

1.5 Low pattern signal View on GitHub

Open-Source Code Quality, Security and Technical Debt Review

This report summarizes scanner evidence for Fission-AI/OpenSpec, a TypeScript project with 73,498 GitHub stars. SynthScan examined 236,713 lines of code across 1277 source files, recording 267 pattern matches distributed across 8 syntactic categories. The legacy adjusted pattern signal is 1.5 (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.

1.5
Adjusted Signal
1.5
Raw Pattern Score
100%
Time Factor
2026-10-30
Last Push
73.5K
Stars
TypeScript
Language
236.7K
Lines of Code
1.3K
Files
267
Pattern Hits
2026-10-31
Scan Date
0.00
HC Hit Rate

Risk Review · Payload v1

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

Payload schema: 1.0.0 · Engine: 2.0.0 · Scoring: heuristic-density-v1 · Scan date: 2026-10-31.

Cognitive Ownership Risk 6.1/100 · LOW

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

Hallucinated Dependency & Supply Chain Risk 0.0/100 · LOW

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

Agent Over-Engineering Ratio 5.2/100 · LOW

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

PR Review Velocity Impact 7.1/100 · LOW

Which changes need focused human review? 267 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 0MEDIUM 40LOW 227

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 267 distinct pattern matches across 8 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 Identifiers195 hits · 198 pts
SeverityFileLineSnippetContext
LOWtest/core/archive.test.ts8655 async function createChangeWithDeltaSpec(changeName: string): Promise<string> {CODE
LOWtest/core/github-copilot-cloud-agent.test.ts108 async function linkDirectoryOutsideProject(outsideDir: string): Promise<void> {CODE
LOWtest/core/update-dry-run.test.ts109 async function expectPlanMatchesRealUpdate(CODE
LOWtest/core/update-dry-run.test.ts120 async function expectFullPlanMatchesRealUpdate(options: { force?: boolean } = {}) {CODE
LOWtest/core/completions/command-registry.test.ts75 function toCommanderPositionalShapes(command: Command): PositionalShape[] {CODE
LOWtest/core/templates/update-change.test.ts113function writeAuthorizationsOutsideStepFive(body: string, label: string): string[] {CODE
LOWtest/core/templates/profile-handoffs.test.ts29function expectInstalledReferences(content: string, workflows: readonly string[], label: string): void {CODE
LOWtest/cli-e2e/store-lifecycle.test.ts107async function writeCompletedChangeArtifacts(CODE
LOWtest/commands/config-profile.test.ts85 function setupDriftedProjectArtifacts(projectDir: string): void {CODE
LOWtest/commands/config-profile.test.ts92 function setupSyncedCoreBothArtifacts(projectDir: string): void {CODE
LOWtest/commands/config-profile.test.ts116 function addExtraVerifyWorkflowArtifacts(projectDir: string): void {CODE
LOWtest/commands/store.test.ts99 function expectHealthyOpenSpecRoot(root: string): void {CODE
LOWtest/commands/store.test.ts106 function expectNoGeneratedAgentOrBetaArtifacts(root: string): void {CODE
LOWtest/commands/legacy-groups-removed.test.ts58 function writeWorkspaceViewFixture(dir: string): void {CODE
LOWtest/helpers/store-git.ts10export function createHealthyOpenSpecRoot(root: string, configName = 'config.yaml'): void {CODE
LOWtest/helpers/run-cli.ts115export function terminateActiveCliChildren(): void {CODE
LOW…/changes/archive/2026-02-17-add-verify-skill/design.md30export function getVerifyChangeSkillTemplate(): SkillTemplateCODE
LOW…/changes/archive/2026-02-17-add-verify-skill/design.md31export function getOpsxVerifyCommandTemplate(): CommandTemplateCODE
LOWsrc/core/legacy-cleanup.ts187function getManagedGlobalLegacyPromptMetadata(filePath: string): LegacyGlobalPromptMatch | undefined {CODE
LOWsrc/core/legacy-cleanup.ts335export async function detectLegacySlashCommands(CODE
LOWsrc/core/legacy-cleanup.ts491async function detectLegacyGlobalPromptFiles(): Promise<LegacyGlobalPromptMatch[]> {CODE
LOWsrc/core/legacy-cleanup.ts523async function findLegacySlashCommandFiles(CODE
LOWsrc/core/legacy-cleanup.ts568export async function detectLegacyStructureFiles(CODE
LOWsrc/core/legacy-cleanup.ts998export function formatDeferredGlobalPromptSummary(detection: LegacyDetectionResult): string {CODE
LOWsrc/core/legacy-cleanup.ts1022export function getToolsFromLegacyArtifacts(detection: LegacyDetectionResult): string[] {CODE
LOWsrc/core/legacy-cleanup.ts1051function legacyManagedFileNamesForDir(dir: string): readonly string[] {CODE
LOWsrc/core/legacy-cleanup.ts1082export function getLegacyGlobalPromptMatches(detection: LegacyDetectionResult): LegacyGlobalPromptMatch[] {CODE
LOWsrc/core/legacy-cleanup.ts1096export function getLegacyWorkflowIdsForTool(CODE
LOWsrc/core/legacy-cleanup.ts1131export function omitGlobalLegacyPromptFiles(detection: LegacyDetectionResult): LegacyDetectionResult {CODE
LOWsrc/core/legacy-cleanup.ts1173export function pickGlobalLegacyPromptFiles(CODE
LOWsrc/core/legacy-cleanup.ts1201export function formatProjectMdMigrationHint(): string {CODE
LOWsrc/core/command-surface.ts17export function resolveCommandSurfaceCapability(toolId: string): CommandSurfaceCapability {CODE
LOW⚡src/core/command-surface.ts29export function shouldGenerateSkillsForTool(toolId: string, delivery: Delivery): boolean {CODE
LOW⚡src/core/command-surface.ts33export function shouldRemoveSkillsForTool(toolId: string, delivery: Delivery): boolean {CODE
LOW⚡src/core/command-surface.ts37export function shouldGenerateCommandsForTool(toolId: string, delivery: Delivery): boolean {CODE
LOW⚡src/core/command-surface.ts41export function shouldReconcileCommandFilesForTool(toolId: string, delivery: Delivery): boolean {CODE
LOWsrc/core/migration.ts200function collectLegacyToolMigrations(CODE
LOWsrc/core/migration.ts521function scanInstalledWorkflowArtifacts(CODE
LOWsrc/core/root-selection.ts302async function resolveNearestOrDeclaredRoot(CODE
LOWsrc/core/root-selection.ts400async function suggestStoreFromGitRemote(CODE
LOWsrc/core/archive.ts98function describeUnaccountedContent(lines: string[]): string {CODE
LOWsrc/core/archive.ts407async function fingerprintDirectoryContents(root: string): Promise<string> {CODE
LOWsrc/core/archive.ts474async function assertCopiedDirectoryUnchanged(CODE
LOWsrc/core/archive.ts514async function listTreeEntriesDeepestFirst(CODE
LOWsrc/core/archive.ts756async function assertArchiveDestinationAvailable(CODE
LOWsrc/core/archive.ts980async function fingerprintPortableContent(filePath: string): Promise<string> {CODE
LOWsrc/core/archive.ts999async function assertRetirementAuthorization(CODE
LOWsrc/core/archive.ts1038async function assertDistinctMutationTargets(mutations: SpecMutation[]): Promise<void> {CODE
LOWsrc/core/archive.ts1265async function finalizeRetirementBackups(CODE
LOWsrc/core/planning-home.ts74export function resolveCurrentPlanningHomeSync(CODE
LOWsrc/core/onboarding-commands.ts61export function formatOptionalWorkflowsNote(CODE
LOWsrc/core/shared-skill-target.ts103export function resolveSharedSkillWriters(CODE
LOWsrc/core/shared-skill-target.ts153export function reconcileSharedSkillTargets(CODE
LOWsrc/core/shared-skill-target.ts223export function isSharedSkillTargetActive(CODE
LOWsrc/core/shared-skill-target.ts264export function sharedSkillRootOwnedByOther(projectPath: string, toolId: string): boolean {CODE
LOWsrc/core/shared-skill-target.ts273export function sharedSkillTargetMarkerPath(projectPath: string, toolId: string): string | null {CODE
LOWsrc/core/profile-sync-drift.ts54export function getConfiguredToolsForProfileSync(CODE
LOWsrc/core/profile-sync-drift.ts69export function hasToolProfileOrDeliveryDrift(CODE
LOWsrc/core/profile-sync-drift.ts183export function getToolsNeedingProfileSync(CODE
LOWsrc/core/profile-sync-drift.ts198function getInstalledWorkflowsForTool(CODE
135 more matches not shown…
Decorative Section Separators18 hits · 54 pts
SeverityFileLineSnippetContext
MEDIUMsrc/core/init.ts380 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts382 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts492 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts494 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts632 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts634 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts895 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts897 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts938 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts940 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts1086 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts1088 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts1178 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/init.ts1180 // ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/core/github-copilot/cloud-agent.ts508// ─────────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMsrc/core/github-copilot/cloud-agent.ts516// ─────────────────────────────────────────────────────────────────────────────COMMENT
MEDIUMsrc/cli/index.ts778// ═══════════════════════════════════════════════════════════COMMENT
MEDIUMsrc/cli/index.ts780// ═══════════════════════════════════════════════════════════COMMENT
Modern AI Meta-Vocabulary18 hits · 48 pts
SeverityFileLineSnippetContext
MEDIUMCHANGELOG.md103- [#2083](https://github.com/Fission-AI/OpenSpec/pull/2083) [`3fea2a9`](https://github.com/Fission-AI/OpenSpec/commit/3fCODE
MEDIUMCHANGELOG.md103- [#2083](https://github.com/Fission-AI/OpenSpec/pull/2083) [`3fea2a9`](https://github.com/Fission-AI/OpenSpec/commit/3fCODE
MEDIUMCHANGELOG.md354- [#1840](https://github.com/Fission-AI/OpenSpec/pull/1840) [`fede536`](https://github.com/Fission-AI/OpenSpec/commit/feCODE
MEDIUMCHANGELOG.md354- [#1840](https://github.com/Fission-AI/OpenSpec/pull/1840) [`fede536`](https://github.com/Fission-AI/OpenSpec/commit/feCODE
MEDIUMCHANGELOG.md430- [#1716](https://github.com/Fission-AI/OpenSpec/pull/1716) [`7010e26`](https://github.com/Fission-AI/OpenSpec/commit/70CODE
MEDIUMCHANGELOG.md430- [#1716](https://github.com/Fission-AI/OpenSpec/pull/1716) [`7010e26`](https://github.com/Fission-AI/OpenSpec/commit/70CODE
MEDIUMtest/explore-docs-claims.test.ts11// made it scaffold with `openspec new change` first. What stays true is narrower: explore never writes code,COMMENT
MEDIUMtest/core/templates/update-change.test.ts141// the guardrails said to write only after the user confirms. "Apply" is a writeCOMMENT
MEDIUM⚡test/core/templates/explore.test.ts741// Regression for #869: the seamless capture path let explore scaffold aCOMMENT
MEDIUM⚡test/core/templates/explore.test.ts741// Regression for #869: the seamless capture path let explore scaffold aCOMMENT
MEDIUMtest/commands/store-root-selection.test.ts812 // scaffold a change into an unrelated repository.COMMENT
MEDIUMtest/commands/declared-store-fallback.test.ts242 // A broken declaration must not be buried under a scaffold.COMMENT
MEDIUMdocs-lab/guides/apply.md9## Managing the context windowCOMMENT
MEDIUMdocs-lab/reference/skills.md57| [openspec-new-change](#openspec-new-change) | Start a change proposal as an empty scaffold | Optional |CODE
MEDIUMdocs-lab/customize/profiles.md28| [`new`](../reference/skills.md#openspec-new-change) | Start a change proposal as an empty scaffold |CODE
MEDIUMdocs/opsx.md190/opsx:new # scaffold onlyCODE
MEDIUM…plify-context-and-workspace-model/workset-direction.md76## 5. Grammar principles (record as standing guardrails)COMMENT
MEDIUMsrc/utils/change-utils.ts175 // Creating a change may scaffold or complete the root itself (anCOMMENT
Over-Commented Block23 hits · 23 pts
SeverityFileLineSnippetContext
LOWpnpm-workspace.yaml1packages:COMMENT
LOWpnpm-workspace.yaml21 # (check: pnpm why js-yaml).COMMENT
LOWtest/explore-docs-claims.test.ts1import { describe, expect, it } from 'vitest';COMMENT
LOWtest/core/specs-apply.salvage.test.ts1import { describe, it, expect, beforeEach, afterEach } from 'vitest';COMMENT
LOWscripts/binary/install.sh1#!/bin/shCOMMENT
LOW.github/dependabot.yml1version: 2COMMENT
LOW.github/workflows/release-prepare.yml61 # Preserve the v1 release path: pushes use the GitHub App token fromCOMMENT
LOW.github/workflows/security.yml81 # manual override.COMMENT
LOWsrc/core/migration.ts41/**COMMENT
LOWsrc/core/archive.ts141 // ordinary write, which fails validation exactly as it always did - and theCOMMENT
LOWsrc/core/archive.ts1461 // Validate proposal.md (informative only; human mode prints warnings)COMMENT
LOWsrc/core/archive.ts1501 let hasDeltaSpecs = rootSpecStat?.isFile() === true;COMMENT
LOWsrc/core/archive.ts1881 // This run is what emptied the capability, and "noCOMMENT
LOWsrc/core/archive.ts2101 wroteAny = true;COMMENT
LOWsrc/core/archive.ts2141 // A command is offered only when pasting it where archive was runCOMMENT
LOWsrc/core/specs-apply.ts861 let bulletsSeen = false;COMMENT
LOWsrc/core/specs-apply.ts881 paragraphOpen = false;COMMENT
LOWsrc/core/specs-apply.ts901 const lazilyContinuesBullet =COMMENT
LOWsrc/core/specs-apply.ts1381 */COMMENT
LOWsrc/core/change-metadata/schema.ts41 .string()COMMENT
LOWsrc/core/shared/tool-detection.ts281): string | null {COMMENT
LOWsrc/core/github-copilot/cloud-agent.ts581 return;COMMENT
LOWsrc/cli/commands/store.ts101 .join(', ');COMMENT
AI Slop Vocabulary3 hits · 12 pts
SeverityFileLineSnippetContext
MEDIUM⚡test/core/templates/explore.test.ts741// Regression for #869: the seamless capture path let explore scaffold aCOMMENT
MEDIUM⚡test/core/templates/explore.test.ts741// Regression for #869: the seamless capture path let explore scaffold aCOMMENT
MEDIUMsrc/commands/workflow/templates.ts59 // Using path.relative is more robust than startsWith for path comparisonsCOMMENT
Structural Annotation Overuse7 hits · 10 pts
SeverityFileLineSnippetContext
LOWREADME_OLD.md141#### Step 1: Install the CLI globallyCOMMENT
LOWREADME_OLD.md187#### Step 2: Initialize OpenSpec in your projectCOMMENT
LOWdocs-lab/start/quickstart.md32## Step 1: ExploreCOMMENT
LOWdocs-lab/start/quickstart.md50## Step 2: ProposeCOMMENT
LOWdocs-lab/start/quickstart.md70## Step 3: Review and correct the planCOMMENT
LOWdocs-lab/start/quickstart.md83## Step 4: ApplyCOMMENT
LOWdocs-lab/start/quickstart.md97## Step 5: ArchiveCOMMENT
Redundant / Tautological Comments2 hits · 3 pts
SeverityFileLineSnippetContext
LOWscripts/update-flake.sh51# Check if pnpm-lock.yaml existsCOMMENT
LOWscripts/update-flake.sh101# Check if hash changedCOMMENT
Self-Referential Comments1 hit · 3 pts
SeverityFileLineSnippetContext
MEDIUMsrc/core/templates/workflows/onboard.ts245## Creating a ChangeCOMMENT