@use-the-fork/spindle 0.0.0-stage → 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +3 -2
- package/build/Assets/Blueprints/Catalog.js +110 -0
- package/build/Assets/Blueprints/agents/general.agent.md +67 -0
- package/build/Assets/Blueprints/agents/sdd-code-reviewer.agent.md +62 -0
- package/build/Assets/Blueprints/agents/sdd-code-slop-reviewer.agent.md +59 -0
- package/build/Assets/Blueprints/agents/sdd-implementer.agent.md +77 -0
- package/build/Assets/Blueprints/agents/sdd-orchestrator.agent.md +42 -0
- package/build/Assets/Blueprints/agents/sdd-re-review.agent.md +57 -0
- package/build/Assets/Blueprints/agents/sdd-reviewer.agent.md +89 -0
- package/build/Assets/Blueprints/agents/sdd-task-reviewer.agent.md +54 -0
- package/build/Assets/Blueprints/agents/shared-codebase-analyzer.agent.md +151 -0
- package/build/Assets/Blueprints/agents/shared-codebase-locator.agent.md +130 -0
- package/build/Assets/Blueprints/agents/shared-codebase-pattern-finder.agent.md +247 -0
- package/build/Assets/Blueprints/agents/shared-explore.agent.md +53 -0
- package/build/Assets/Blueprints/agents/shared-r.agent.md +17 -0
- package/build/Assets/Blueprints/agents/shared-rw.agent.md +17 -0
- package/build/Assets/Blueprints/agents/shared-rwx.agent.md +17 -0
- package/build/Assets/Blueprints/agents/shared-web-search-researcher.agent.md +122 -0
- package/build/Assets/Blueprints/instructions/code-commenting.instructions.md +39 -0
- package/build/Assets/Blueprints/instructions/source-architecture.instructions.md +15 -0
- package/build/Assets/Blueprints/skills/asd-ste100/CREDITS.MD +1 -0
- package/build/Assets/Blueprints/skills/asd-ste100/SKILL.md +83 -0
- package/build/Assets/Blueprints/skills/asd-ste100/examples/before-after.md +107 -0
- package/build/Assets/Blueprints/skills/asd-ste100/references/writing-rules.md +65 -0
- package/build/Assets/Blueprints/skills/author-agent/SKILL.md +26 -0
- package/build/Assets/Blueprints/skills/author-design/SKILL.md +38 -0
- package/build/Assets/Blueprints/skills/author-instruction/SKILL.md +28 -0
- package/build/Assets/Blueprints/skills/author-skill/SKILL.md +26 -0
- package/build/Assets/Blueprints/skills/grill/SKILL.md +33 -0
- package/build/Assets/Blueprints/skills/grill-design/SKILL.md +41 -0
- package/build/Assets/Blueprints/skills/grill-with-docs/SKILL.md +14 -0
- package/build/Assets/Blueprints/skills/implement/SKILL.md +79 -0
- package/build/Assets/Blueprints/skills/implement-spec/SKILL.md +34 -0
- package/build/Assets/Blueprints/skills/improve-codebase-architecture/HTML-REPORT.md +129 -0
- package/build/Assets/Blueprints/skills/improve-codebase-architecture/SKILL.md +74 -0
- package/build/Assets/Blueprints/skills/int-code-review/SKILL.md +76 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/SKILL.md +238 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/_sections.md +36 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/_template.md +42 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/comments-closing-brace-labels.md +112 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/comments-empty-docblocks.md +132 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/comments-narration.md +118 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/comments-placeholder.md +130 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/defensive-generic-catch.md +153 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/defensive-impossible-null.md +157 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/defensive-missing-real.md +157 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/naming-generic-placeholders.md +120 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/naming-over-descriptive.md +108 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/naming-suffix-abuse.md +167 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/naming-type-in-name.md +100 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/over-eng-dependency-creep.md +114 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/over-eng-premature-interface.md +136 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/over-eng-single-method-class.md +161 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/over-eng-useless-wrapper.md +140 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-as-any-escape.md +127 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-debug-artifacts.md +144 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-hyper-consistent.md +84 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-no-hack-scars.md +113 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/style-trivial-boilerplate.md +191 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/test-doesnt-throw.md +132 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/test-mirror-implementation.md +125 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/test-mock-everything.md +148 -0
- package/build/Assets/Blueprints/skills/int-code-slop-review/rules/test-snapshot-abuse.md +131 -0
- package/build/Assets/Blueprints/skills/int-codebase-design/SKILL.md +116 -0
- package/build/Assets/Blueprints/skills/int-codebase-design/references/DEEPENING.md +37 -0
- package/build/Assets/Blueprints/skills/int-codebase-design/references/DESIGN-IT-TWICE.md +44 -0
- package/build/Assets/Blueprints/skills/int-domain-modeling/SKILL.md +78 -0
- package/build/Assets/Blueprints/skills/int-domain-modeling/references/ADR-FORMAT.md +47 -0
- package/build/Assets/Blueprints/skills/int-domain-modeling/references/GLOSSARY-FORMAT.md +60 -0
- package/build/Assets/Blueprints/skills/int-prototype/LOGIC.md +67 -0
- package/build/Assets/Blueprints/skills/int-prototype/SKILL.md +30 -0
- package/build/Assets/Blueprints/skills/int-prototype/UI.md +112 -0
- package/build/Assets/Blueprints/skills/int-retrospective/SKILL.md +88 -0
- package/build/Assets/Blueprints/skills/int-retrospective/assets/retrospective-prompt.md +38 -0
- package/build/Assets/Blueprints/skills/int-retrospective/references/assessment.md +56 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/SKILL.md +64 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/assets/implementer-prompt.md +40 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/assets/reviewer-prompt.md +43 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/aggregate-review.md +7 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/corrective-rounds.md +72 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/example-workflow.md +25 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/full-spec.md +72 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/implementer-corrections.md +9 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/review-inputs.md +26 -0
- package/build/Assets/Blueprints/skills/int-subagent-driven-dev/references/verification-evidence.md +7 -0
- package/build/Assets/Blueprints/skills/int-test-driven-development/SKILL.md +51 -0
- package/build/Assets/Blueprints/skills/int-test-driven-development/references/mocking.md +31 -0
- package/build/Assets/Blueprints/skills/int-test-driven-development/references/tests.md +68 -0
- package/build/Assets/Blueprints/skills/int-testing-agent-guidance/SKILL.md +53 -0
- package/build/Assets/Blueprints/skills/int-verification-before-completion/SKILL.md +25 -0
- package/build/Assets/Blueprints/skills/int-writing-agents/SKILL.md +66 -0
- package/build/Assets/Blueprints/skills/int-writing-for-agents/SKILL.md +86 -0
- package/build/Assets/Blueprints/skills/int-writing-instruction/SKILL.md +57 -0
- package/build/Assets/Blueprints/skills/int-writing-skills/SKILL.md +129 -0
- package/build/Assets/Blueprints/skills/int-writing-skills/assets/interactive.md +83 -0
- package/build/Assets/Blueprints/skills/int-writing-skills/assets/reference.md +32 -0
- package/build/Assets/Blueprints/skills/int-writing-skills/references/arguments.md +50 -0
- package/build/Assets/Blueprints/skills/int-writing-skills/references/interactive-skills.md +53 -0
- package/build/Assets/Blueprints/skills/int-writing-skills/references/persuasion-principles.md +220 -0
- package/build/Assets/Blueprints/skills/int-writing-skills/references/reference-skills.md +20 -0
- package/build/Assets/Blueprints/skills/int-writing-skills/references/testing-skills.md +48 -0
- package/build/Assets/Blueprints/skills/retrospective/SKILL.md +16 -0
- package/build/Assets/Blueprints/skills/setup-project/SKILL.md +66 -0
- package/build/Assets/Blueprints/skills/to-spec/SKILL.md +53 -0
- package/build/Assets/Blueprints/skills/to-tickets/SKILL.md +49 -0
- package/build/Assets/Blueprints/skills/update-tooling/SKILL.md +86 -0
- package/build/Assets/Templates/Catalog.js +12 -0
- package/build/Assets/Templates/Catalog.ts +17 -0
- package/build/Assets/Templates/project/copilot-instructions.md +17 -0
- package/build/Assets/Templates/project/domain.md +51 -0
- package/build/Assets/Templates/project/ticket-tracker.md +33 -0
- package/build/Assets/Templates/sdd/design.md +25 -0
- package/build/Assets/Templates/sdd/spec.md +29 -0
- package/build/Assets/Templates/sdd/ticket.md +15 -0
- package/build/BlueprintManagement/BlueprintManagementServiceProvider.js +15 -0
- package/build/BlueprintManagement/Catalog/BlueprintCatalog.js +238 -0
- package/build/BlueprintManagement/Commands/BlueprintCommandOptions.js +9 -0
- package/build/BlueprintManagement/Commands/ConflictPolicy.js +6 -0
- package/build/BlueprintManagement/Commands/InitCommand.js +117 -0
- package/build/BlueprintManagement/Commands/Prompts.js +66 -0
- package/build/BlueprintManagement/Commands/UpdateCommand.js +86 -0
- package/build/BlueprintManagement/Handlers/Agents/AgentHandler.js +21 -0
- package/build/BlueprintManagement/Handlers/BlueprintHandlers.js +4 -0
- package/build/BlueprintManagement/Handlers/Instructions/InstructionHandler.js +21 -0
- package/build/BlueprintManagement/Handlers/Skills/SkillHandler.js +10 -0
- package/build/BlueprintManagement/Reconciliation/BlueprintCatalogPlanner.js +87 -0
- package/build/BlueprintManagement/Reconciliation/BlueprintRemovalCoordinator.js +78 -0
- package/build/BlueprintManagement/Services/BlueprintReconciliationService.js +391 -0
- package/build/BlueprintManagement/Services/InstallationService.js +54 -0
- package/build/BlueprintManagement/Support/BlueprintFiles.js +113 -0
- package/build/BlueprintManagement/Types/Blueprint.js +1 -0
- package/build/BlueprintManagement/Types/Installation.js +1 -0
- package/build/BlueprintManagement/Types/Reconciliation.js +1 -0
- package/build/BlueprintManagement/Versioning/BlueprintVersion.js +70 -0
- package/build/BlueprintManagement/Versioning/BlueprintVersioning.js +55 -0
- package/build/Commands/Command.js +3 -0
- package/build/Commands/CommandOptions.js +12 -0
- package/build/Config/Config.js +3 -0
- package/build/Foundation/Application.js +112 -0
- package/build/Foundation/ApplicationBuilder.js +23 -0
- package/build/Foundation/Bootstrap/Bootstrapper.js +2 -0
- package/build/Foundation/Bootstrap/DiscoverGitRoot.js +8 -0
- package/build/Foundation/Bootstrap/LoadConsoleArgs.js +47 -0
- package/build/Foundation/Bootstrap/LoadProjectConfiguration.js +144 -0
- package/build/Foundation/Bootstrap/RegisterProviders.js +12 -0
- package/build/Foundation/Bootstrap/RequireProjectConfiguration.js +14 -0
- package/build/Foundation/ConsoleInvocation.js +1 -0
- package/build/Foundation/Container.js +185 -0
- package/build/Foundation/FoundationServiceProvider.js +5 -0
- package/build/Foundation/Kernel.js +30 -0
- package/build/Foundation/Service.js +23 -0
- package/build/Foundation/ServiceProvider.js +12 -0
- package/build/Git/GitServiceProvider.js +8 -0
- package/build/Git/Services/GitService.js +26 -0
- package/build/Project/ProjectServiceProvider.js +8 -0
- package/build/Project/Services/ProjectService.js +124 -0
- package/build/SubagentDrivenDevelopment/Commands/ChecksRecordCommand.js +35 -0
- package/build/SubagentDrivenDevelopment/Commands/ChecksRequireCommand.js +33 -0
- package/build/SubagentDrivenDevelopment/Commands/ClaimCommand.js +23 -0
- package/build/SubagentDrivenDevelopment/Commands/CorrectCommand.js +37 -0
- package/build/SubagentDrivenDevelopment/Commands/CreateCommand.js +26 -0
- package/build/SubagentDrivenDevelopment/Commands/FindingCreateCommand.js +39 -0
- package/build/SubagentDrivenDevelopment/Commands/FindingUpdateCommand.js +36 -0
- package/build/SubagentDrivenDevelopment/Commands/FinishCommand.js +23 -0
- package/build/SubagentDrivenDevelopment/Commands/ImplementCommand.js +23 -0
- package/build/SubagentDrivenDevelopment/Commands/NextCommand.js +21 -0
- package/build/SubagentDrivenDevelopment/Commands/ReadyCommand.js +21 -0
- package/build/SubagentDrivenDevelopment/Commands/RequirementsDecideCommand.js +33 -0
- package/build/SubagentDrivenDevelopment/Commands/ResumeCommand.js +31 -0
- package/build/SubagentDrivenDevelopment/Commands/ReviewCommand.js +55 -0
- package/build/SubagentDrivenDevelopment/Commands/ReviewRequireCommand.js +12 -0
- package/build/SubagentDrivenDevelopment/Commands/StatusCommand.js +21 -0
- package/build/SubagentDrivenDevelopment/Commands/SubmitCommand.js +59 -0
- package/build/SubagentDrivenDevelopment/Commands/TicketCommentCommand.js +24 -0
- package/build/SubagentDrivenDevelopment/Commands/TicketCreateCommand.js +25 -0
- package/build/SubagentDrivenDevelopment/Commands/TicketUpdateCommand.js +31 -0
- package/build/SubagentDrivenDevelopment/Commands/groups.js +36 -0
- package/build/SubagentDrivenDevelopment/Evidence/GitEvidence.js +449 -0
- package/build/SubagentDrivenDevelopment/Evidence/ReportEvidence.js +80 -0
- package/build/SubagentDrivenDevelopment/Models/Assignments.js +1 -0
- package/build/SubagentDrivenDevelopment/Models/Evidence.js +1 -0
- package/build/SubagentDrivenDevelopment/Models/Findings.js +1 -0
- package/build/SubagentDrivenDevelopment/Models/Options.js +1 -0
- package/build/SubagentDrivenDevelopment/Models/Workflow.js +16 -0
- package/build/SubagentDrivenDevelopment/Persistence/AssignmentSchema.js +155 -0
- package/build/SubagentDrivenDevelopment/Persistence/CheckSchema.js +71 -0
- package/build/SubagentDrivenDevelopment/Persistence/FeatureWorkspace.js +76 -0
- package/build/SubagentDrivenDevelopment/Persistence/FileSystem.js +28 -0
- package/build/SubagentDrivenDevelopment/Persistence/FindingSchema.js +81 -0
- package/build/SubagentDrivenDevelopment/Persistence/LedgerRepository.js +322 -0
- package/build/SubagentDrivenDevelopment/Persistence/PathSafety.js +62 -0
- package/build/SubagentDrivenDevelopment/Persistence/ProgressSchema.js +95 -0
- package/build/SubagentDrivenDevelopment/Persistence/ReadinessReader.js +40 -0
- package/build/SubagentDrivenDevelopment/Persistence/ReviewSchema.js +68 -0
- package/build/SubagentDrivenDevelopment/Persistence/TicketRepository.js +147 -0
- package/build/SubagentDrivenDevelopment/Persistence/WorkspaceTransaction.js +282 -0
- package/build/SubagentDrivenDevelopment/Policies/AcceptancePolicy.js +100 -0
- package/build/SubagentDrivenDevelopment/Policies/AssignmentPolicy.js +36 -0
- package/build/SubagentDrivenDevelopment/Policies/CheckPolicy.js +93 -0
- package/build/SubagentDrivenDevelopment/Policies/FindingPolicy.js +53 -0
- package/build/SubagentDrivenDevelopment/Policies/InputValidation.js +36 -0
- package/build/SubagentDrivenDevelopment/Policies/ReadinessPolicy.js +26 -0
- package/build/SubagentDrivenDevelopment/Policies/RequiredReviewers.js +12 -0
- package/build/SubagentDrivenDevelopment/Policies/ReviewPolicy.js +87 -0
- package/build/SubagentDrivenDevelopment/Policies/WorkflowPolicy.js +85 -0
- package/build/SubagentDrivenDevelopment/Services/AssignmentService.js +269 -0
- package/build/SubagentDrivenDevelopment/Services/ChecksService.js +319 -0
- package/build/SubagentDrivenDevelopment/Services/CorrectionService.js +273 -0
- package/build/SubagentDrivenDevelopment/Services/DeliveryCorrectionService.js +253 -0
- package/build/SubagentDrivenDevelopment/Services/DeliveryFindingService.js +302 -0
- package/build/SubagentDrivenDevelopment/Services/DeliveryService.js +160 -0
- package/build/SubagentDrivenDevelopment/Services/DeliverySubmissionService.js +273 -0
- package/build/SubagentDrivenDevelopment/Services/FeatureCreationService.js +138 -0
- package/build/SubagentDrivenDevelopment/Services/FeatureInspectionService.js +399 -0
- package/build/SubagentDrivenDevelopment/Services/FindingService.js +392 -0
- package/build/SubagentDrivenDevelopment/Services/IntegrationService.js +258 -0
- package/build/SubagentDrivenDevelopment/Services/ReadinessService.js +21 -0
- package/build/SubagentDrivenDevelopment/Services/RequirementsService.js +216 -0
- package/build/SubagentDrivenDevelopment/Services/ReviewService.js +471 -0
- package/build/SubagentDrivenDevelopment/Services/SubmissionService.js +299 -0
- package/build/SubagentDrivenDevelopment/Services/TicketService.js +186 -0
- package/build/SubagentDrivenDevelopment/SubagentDrivenDevelopmentServiceProvider.js +113 -0
- package/build/Support/Records.js +5 -0
- package/build/Support/Repository.js +139 -0
- package/build/Support/Stacks.js +10 -0
- package/build/TemplateRendering/Computed/ComputedContextService.js +13 -0
- package/build/TemplateRendering/Computed/ComputedVariableProvider.js +6 -0
- package/build/TemplateRendering/Computed/ComputedVariableProviders.js +6 -0
- package/build/TemplateRendering/Computed/Providers/InternalSkillDescriptionProvider.js +6 -0
- package/build/TemplateRendering/Computed/Providers/SpindlePackageManagerProvider.js +11 -0
- package/build/TemplateRendering/Computed/ResolveRenderContext.js +18 -0
- package/build/TemplateRendering/Rendering/RenderText.js +43 -0
- package/build/TemplateRendering/TemplateRenderingServiceProvider.js +8 -0
- package/build/Tooling/Commands/ToolingAddCommand.js +29 -0
- package/build/Tooling/Commands/ToolingListCommand.js +19 -0
- package/build/Tooling/Commands/ToolingRemoveCommand.js +19 -0
- package/build/Tooling/Commands/ToolingUpdateCommand.js +30 -0
- package/build/Tooling/Commands/groups.js +4 -0
- package/build/Tooling/Models/ToolingEntry.js +1 -0
- package/build/Tooling/Services/ToolingService.js +278 -0
- package/build/Tooling/ToolingServiceProvider.js +15 -0
- package/build/cli.js +36 -0
- package/build/index.js +31 -0
- package/package.json +54 -3
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: int-code-slop-review
|
|
3
|
+
description: "{{ computed.internal_skill_description }}"
|
|
4
|
+
user-invocable: false
|
|
5
|
+
metadata:
|
|
6
|
+
spindle:
|
|
7
|
+
version: 1.0.0
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# Code-Slop Review
|
|
11
|
+
|
|
12
|
+
Review a specific code change for avoidable complexity that makes the implementation harder to understand, change, or trust. This is a focused maintainability review, not a general correctness or style review.
|
|
13
|
+
|
|
14
|
+
## How to Audit
|
|
15
|
+
|
|
16
|
+
Run through this skill's rules as a checklist against the changed files (PR diff) or full repo.
|
|
17
|
+
|
|
18
|
+
### Audit Step 1: Determine Scope
|
|
19
|
+
|
|
20
|
+
- If a PR diff is provided: audit only files changed in the diff
|
|
21
|
+
- If files are named: audit those
|
|
22
|
+
- If no scope: audit the whole repo, prioritized by recently-touched files (most likely AI output)
|
|
23
|
+
|
|
24
|
+
### Audit Step 2: Detect Stack
|
|
25
|
+
|
|
26
|
+
| Signal | Stack |
|
|
27
|
+
| ------------------------------------------- | ------------------------- |
|
|
28
|
+
| `composer.json` + `artisan` | PHP / Laravel |
|
|
29
|
+
| `package.json` (with TypeScript/React deps) | Node / TypeScript / React |
|
|
30
|
+
| Both present | Laravel + Inertia + React |
|
|
31
|
+
|
|
32
|
+
### Audit Step 3: Run the Slop Checklist
|
|
33
|
+
|
|
34
|
+
For each item below, output:
|
|
35
|
+
|
|
36
|
+
- **CLEAN** — pattern not present (brief confirmation)
|
|
37
|
+
- **SUSPICIOUS** — present in small amounts; flag and discuss
|
|
38
|
+
- **INFLATED** — present extensively; verbose-but-functional; remediation recommended
|
|
39
|
+
- **CRITICAL** — extensive AI-fingerprint presence; full review needed before merge
|
|
40
|
+
|
|
41
|
+
#### Comments
|
|
42
|
+
|
|
43
|
+
- [ ] No comments that just narrate the code (`// create user` above `User::create(...)`)
|
|
44
|
+
- [ ] No empty docblocks (`/** Get user */` above `getUser()`)
|
|
45
|
+
- [ ] No placeholder comments left in (`// TODO: implement`, `// your code here`, `// implementation`)
|
|
46
|
+
- [ ] No closing-brace labels (`} // end function`, `} // end if block`)
|
|
47
|
+
|
|
48
|
+
#### Naming
|
|
49
|
+
|
|
50
|
+
- [ ] No generic placeholder names (`data`, `result`, `info`, `temp`, `helper`)
|
|
51
|
+
- [ ] No over-descriptive run-on names (`theUserWhoIsCurrentlyLoggedIn`)
|
|
52
|
+
- [ ] No suffix abuse (`*Helper` / `*Manager` / `*Util` / `*Wrapper` overused without justification)
|
|
53
|
+
- [ ] No type-in-name patterns (`userObject`, `resultArray`, `stringData`)
|
|
54
|
+
|
|
55
|
+
#### Over-engineering
|
|
56
|
+
|
|
57
|
+
- [ ] No interfaces with exactly one implementation (and no plan for a second)
|
|
58
|
+
- [ ] No single-method classes that should be top-level functions
|
|
59
|
+
- [ ] No wrapper functions called once that just delegate
|
|
60
|
+
- [ ] No new dependency added when an existing one does the same job
|
|
61
|
+
|
|
62
|
+
#### Defensive overdose
|
|
63
|
+
|
|
64
|
+
- [ ] No generic `catch (e) { console.error(...) }` blocks around code that can't throw
|
|
65
|
+
- [ ] No null checks for impossible nulls (after non-null assertions / type-guaranteed values)
|
|
66
|
+
- [ ] Real defensive concerns (timeouts on external calls, rate limits) ARE present
|
|
67
|
+
|
|
68
|
+
#### Test slop
|
|
69
|
+
|
|
70
|
+
- [ ] No tests that mock every dependency with no real behavioural assertion
|
|
71
|
+
- [ ] No "doesn't throw" tests that just call and check for exceptions
|
|
72
|
+
- [ ] No tests that mirror the implementation's logic (re-encoding rather than verifying)
|
|
73
|
+
- [ ] No snapshot tests standing in for behavioural assertions
|
|
74
|
+
|
|
75
|
+
#### Style fingerprints
|
|
76
|
+
|
|
77
|
+
- [ ] Some formatting drift exists (no codebase looks like every file ran through the most aggressive linter)
|
|
78
|
+
- [ ] No `as any` / `@ts-ignore` / `@ts-expect-error` sprinkled where inference is hard
|
|
79
|
+
- [ ] Repo has some `// HACK:` / `// XXX:` / 2am comments somewhere — codebases without scars are suspect
|
|
80
|
+
- [ ] No debug artifacts (`console.log`, `var_dump`, `dd()`, `dump()`) left in production code
|
|
81
|
+
- [ ] No `if (x) return true; else return false` / redundant type annotations on obvious literals
|
|
82
|
+
|
|
83
|
+
### Audit Step 4: Build the Slop Ledger
|
|
84
|
+
|
|
85
|
+
End the audit with a verdict table:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
## Code Slop Ledger
|
|
89
|
+
|
|
90
|
+
| File | Verdict | Top findings | Suggested action |
|
|
91
|
+
|------|---------|--------------|------------------|
|
|
92
|
+
| app/Services/UserExportService.php | INFLATED | 12 narration comments; 3 closing-brace labels; `*Helper` overuse | Strip comments; rename Helper → split into functions |
|
|
93
|
+
| resources/js/Pages/Orders/Show.tsx | CRITICAL | 4 `as any`; mock-everything tests; useless wrapper; impossible null checks | Rewrite section; remove tests; revisit type model |
|
|
94
|
+
| app/Models/Order.php | CLEAN | — | — |
|
|
95
|
+
|
|
96
|
+
## Summary
|
|
97
|
+
- CLEAN: X files
|
|
98
|
+
- SUSPICIOUS: Y files
|
|
99
|
+
- INFLATED: Z files (top priority: …)
|
|
100
|
+
- CRITICAL: N files (rewrite before merge)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## When to Apply
|
|
104
|
+
|
|
105
|
+
Reference this skill when:
|
|
106
|
+
|
|
107
|
+
- Reviewing an AI-assisted PR before merge
|
|
108
|
+
- Auditing a repo that has accepted heavy AI-assisted contributions
|
|
109
|
+
- Onboarding a codebase and assessing whether it reads as human-maintained
|
|
110
|
+
- Hardening a team's code-review checklist against AI slop
|
|
111
|
+
- After a "vibe coding" sprint, before declaring features done
|
|
112
|
+
- Setting up CI gates for AI-output quality
|
|
113
|
+
|
|
114
|
+
## Step 1: Detect Project Stack
|
|
115
|
+
|
|
116
|
+
Most rules are stack-agnostic in concept, but examples and detection commands differ between PHP and TypeScript.
|
|
117
|
+
|
|
118
|
+
| Signal | Stack | Tooling |
|
|
119
|
+
| --------------- | ----------------- | ---------------------------------------------------------- |
|
|
120
|
+
| `composer.json` | PHP / Laravel | `mago lint`, `mago analyze`, `phpcs`, `phpmd`, manual grep |
|
|
121
|
+
| `package.json` | Node / TS / React | `oxlint`, `tsc --noEmit`, `knip`, manual grep |
|
|
122
|
+
|
|
123
|
+
## Rule Categories by Priority
|
|
124
|
+
|
|
125
|
+
| Priority | Category | Impact | Prefix |
|
|
126
|
+
| -------- | ------------------ | -------- | ------------ |
|
|
127
|
+
| 1 | Comments | CRITICAL | `comments-` |
|
|
128
|
+
| 2 | Naming | CRITICAL | `naming-` |
|
|
129
|
+
| 3 | Over-engineering | HIGH | `over-eng-` |
|
|
130
|
+
| 4 | Defensive overdose | HIGH | `defensive-` |
|
|
131
|
+
| 5 | Test slop | HIGH | `test-` |
|
|
132
|
+
| 6 | Style fingerprints | MEDIUM | `style-` |
|
|
133
|
+
|
|
134
|
+
## Quick Reference
|
|
135
|
+
|
|
136
|
+
### 1. Comments (CRITICAL)
|
|
137
|
+
|
|
138
|
+
- `comments-narration` — Comments that just restate the code on the next line
|
|
139
|
+
- `comments-empty-docblocks` — Generic `/** Get the user */` over a typed `getUser()` signature
|
|
140
|
+
- `comments-placeholder` — `// TODO: implement`, `// your code here`, `// implementation`, `// helper function`
|
|
141
|
+
- `comments-closing-brace-labels` — `} // end function` / `} // end if block`
|
|
142
|
+
|
|
143
|
+
### 2. Naming (CRITICAL)
|
|
144
|
+
|
|
145
|
+
- `naming-generic-placeholders` — `data`, `result`, `info`, `temp`, `helper`, `value`
|
|
146
|
+
- `naming-over-descriptive` — `theUserWhoIsCurrentlyLoggedIn`, `calculateTotalAmountFromItemsList`
|
|
147
|
+
- `naming-suffix-abuse` — `*Helper` / `*Manager` / `*Util` / `*Wrapper` / `*Processor` overused
|
|
148
|
+
- `naming-type-in-name` — `userObject`, `resultArray`, `stringData`, `listOfItems`
|
|
149
|
+
|
|
150
|
+
### 3. Over-engineering (HIGH)
|
|
151
|
+
|
|
152
|
+
- `over-eng-premature-interface` — Interface with exactly one implementation and no second on the roadmap
|
|
153
|
+
- `over-eng-single-method-class` — Classes that exist solely to wrap one function
|
|
154
|
+
- `over-eng-useless-wrapper` — Wrapper called from exactly one place, just delegating
|
|
155
|
+
- `over-eng-dependency-creep` — New library when an existing dep already does the job
|
|
156
|
+
|
|
157
|
+
### 4. Defensive overdose (HIGH)
|
|
158
|
+
|
|
159
|
+
- `defensive-generic-catch` — `try { ... } catch (e) { console.error("error") }` everywhere
|
|
160
|
+
- `defensive-impossible-null` — Null checks after non-null assertions / type-guaranteed values
|
|
161
|
+
- `defensive-missing-real` — Defensive in the wrong places; missing timeouts/rate-limits where it matters
|
|
162
|
+
|
|
163
|
+
### 5. Test slop (HIGH)
|
|
164
|
+
|
|
165
|
+
- `test-mock-everything` — Mock for every dep; the test re-encodes the implementation, not the behaviour
|
|
166
|
+
- `test-doesnt-throw` — Tests that just call the function and assert no exception
|
|
167
|
+
- `test-mirror-implementation` — Tests whose logic mirrors the production code being tested
|
|
168
|
+
- `test-snapshot-abuse` — Snapshot tests replacing behavioural assertions
|
|
169
|
+
|
|
170
|
+
### 6. Style fingerprints (MEDIUM)
|
|
171
|
+
|
|
172
|
+
- `style-hyper-consistent` — No formatting drift anywhere; every file looks linter-perfect
|
|
173
|
+
- `style-as-any-escape` — `as any` / `@ts-ignore` / `@ts-expect-error` sprinkled where types are hard
|
|
174
|
+
- `style-no-hack-scars` — Codebase has zero `// HACK:` / `// XXX:` markers; no "geology"
|
|
175
|
+
- `style-debug-artifacts` — `console.log`, `var_dump`, `dd()`, `dump()` left in production paths
|
|
176
|
+
- `style-trivial-boilerplate` — `if (x) return true; else return false;`, redundant TS type annotations on obvious literals
|
|
177
|
+
|
|
178
|
+
## Essential Patterns
|
|
179
|
+
|
|
180
|
+
### The "would this pass code review?" filter
|
|
181
|
+
|
|
182
|
+
For each code chunk, ask:
|
|
183
|
+
|
|
184
|
+
1. **Could I cut a third of these comments and the code would be clearer?** → likely comment slop
|
|
185
|
+
2. **Do the variable names tell me what they hold, or just what type they are?** → likely naming slop
|
|
186
|
+
3. **Could this class be a function?** → likely over-engineering
|
|
187
|
+
4. **Does this catch block actually handle anything, or just log?** → likely defensive overdose
|
|
188
|
+
5. **Does this test fail if I break the function?** → if no, test slop
|
|
189
|
+
6. **Are there any `// HACK:` / `// XXX:` markers in the diff?** → if no, suspicious for AI
|
|
190
|
+
|
|
191
|
+
### Verdict bands (matched to AI-SLOP-Detector's scoring)
|
|
192
|
+
|
|
193
|
+
| Verdict | Meaning | Action |
|
|
194
|
+
| -------------- | --------------------- | ---------------------------- |
|
|
195
|
+
| **CLEAN** | < 5% of lines flagged | Ship |
|
|
196
|
+
| **SUSPICIOUS** | 5–15% flagged | Review changes one more time |
|
|
197
|
+
| **INFLATED** | 15–30% flagged | Strip slop, split commits |
|
|
198
|
+
| **CRITICAL** | > 30% flagged | Rewrite section before merge |
|
|
199
|
+
|
|
200
|
+
## How to Use
|
|
201
|
+
|
|
202
|
+
Read individual rule files for detailed conventions and examples:
|
|
203
|
+
|
|
204
|
+
- [comments-closing-brace-labels.md](rules/comments-closing-brace-labels.md)
|
|
205
|
+
- [comments-empty-docblocks.md](rules/comments-empty-docblocks.md)
|
|
206
|
+
- [comments-narration.md](rules/comments-narration.md)
|
|
207
|
+
- [comments-placeholder.md](rules/comments-placeholder.md)
|
|
208
|
+
- [defensive-generic-catch.md](rules/defensive-generic-catch.md)
|
|
209
|
+
- [defensive-impossible-null.md](rules/defensive-impossible-null.md)
|
|
210
|
+
- [defensive-missing-real.md](rules/defensive-missing-real.md)
|
|
211
|
+
- [naming-generic-placeholders.md](rules/naming-generic-placeholders.md)
|
|
212
|
+
- [naming-over-descriptive.md](rules/naming-over-descriptive.md)
|
|
213
|
+
- [naming-suffix-abuse.md](rules/naming-suffix-abuse.md)
|
|
214
|
+
- [naming-type-in-name.md](rules/naming-type-in-name.md)
|
|
215
|
+
- [over-eng-dependency-creep.md](rules/over-eng-dependency-creep.md)
|
|
216
|
+
- [over-eng-premature-interface.md](rules/over-eng-premature-interface.md)
|
|
217
|
+
- [over-eng-single-method-class.md](rules/over-eng-single-method-class.md)
|
|
218
|
+
- [over-eng-useless-wrapper.md](rules/over-eng-useless-wrapper.md)
|
|
219
|
+
- [style-as-any-escape.md](rules/style-as-any-escape.md)
|
|
220
|
+
- [style-debug-artifacts.md](rules/style-debug-artifacts.md)
|
|
221
|
+
- [style-hyper-consistent.md](rules/style-hyper-consistent.md)
|
|
222
|
+
- [style-no-hack-scars.md](rules/style-no-hack-scars.md)
|
|
223
|
+
- [style-trivial-boilerplate.md](rules/style-trivial-boilerplate.md)
|
|
224
|
+
- [test-doesnt-throw.md](rules/test-doesnt-throw.md)
|
|
225
|
+
- [test-mirror-implementation.md](rules/test-mirror-implementation.md)
|
|
226
|
+
- [test-mock-everything.md](rules/test-mock-everything.md)
|
|
227
|
+
- [test-snapshot-abuse.md](rules/test-snapshot-abuse.md)
|
|
228
|
+
|
|
229
|
+
Each rule file contains:
|
|
230
|
+
|
|
231
|
+
- YAML frontmatter (title, impact, tags)
|
|
232
|
+
- Brief explanation of why the pattern is AI-fingerprint
|
|
233
|
+
- "Incorrect" example showing the slop
|
|
234
|
+
- "Correct" example showing the human-equivalent
|
|
235
|
+
- Detection guidance (grep / oxlint / mago / heuristic)
|
|
236
|
+
- Reference link
|
|
237
|
+
|
|
238
|
+
Supporting references: [section definitions](rules/_sections.md) and [rule template](rules/_template.md).
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Sections
|
|
2
|
+
|
|
3
|
+
This file defines all sections, their ordering, impact levels, and descriptions.
|
|
4
|
+
The section ID (in parentheses) is the filename prefix used to group rules.
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 1. Comments (comments)
|
|
9
|
+
|
|
10
|
+
**Impact:** CRITICAL
|
|
11
|
+
**Description:** The single loudest AI tell. Models love to narrate the next line in the comment above it, write empty docblocks that restate the function signature, and leave placeholder comments like `// TODO: implement` long after the code shipped. Cleaning these out is the fastest path to "this looks human-written".
|
|
12
|
+
|
|
13
|
+
## 2. Naming (naming)
|
|
14
|
+
|
|
15
|
+
**Impact:** CRITICAL
|
|
16
|
+
**Description:** AI-generated code swings between two opposite failure modes — generic placeholders (`data`, `result`, `info`) and over-descriptive run-ons (`theUserWhoIsCurrentlyLoggedIn`) — often in the same file. A human teammate converges on a register. Suffix abuse (`*Helper`, `*Manager`, `*Util`) and type-in-name patterns (`userObject`, `resultArray`) round out the family.
|
|
17
|
+
|
|
18
|
+
## 3. Over-engineering (over-eng)
|
|
19
|
+
|
|
20
|
+
**Impact:** HIGH
|
|
21
|
+
**Description:** Adding layers nobody asked for. Premature interfaces with one implementation, single-method classes that should be functions, wrappers called from one place, and pulling in a new dependency when an existing one does the job. AI defaults to "enterprise-grade" because its training distribution is enterprise-grade.
|
|
22
|
+
|
|
23
|
+
## 4. Defensive overdose (defensive)
|
|
24
|
+
|
|
25
|
+
**Impact:** HIGH
|
|
26
|
+
**Description:** Try/catch wrapped around code that can't throw. Null checks after a non-null assertion. `if (array && array.length > 0)` three times in the same function. Meanwhile real defenses (timeouts on external calls, rate limits, circuit breakers) are missing. AI is defensive in the wrong places.
|
|
27
|
+
|
|
28
|
+
## 5. Test slop (test)
|
|
29
|
+
|
|
30
|
+
**Impact:** HIGH
|
|
31
|
+
**Description:** Tests that mock everything and assert nothing. Tests that mirror the implementation's logic — they pass because they re-encode the same code, not because they verify Behavior. "Doesn't throw" assertions that don't check anything meaningful. Snapshot abuse instead of behavioral assertions.
|
|
32
|
+
|
|
33
|
+
## 6. Style fingerprints (style)
|
|
34
|
+
|
|
35
|
+
**Impact:** MEDIUM
|
|
36
|
+
**Description:** The small tells: hyper-consistent formatting (no human drift), `as any` / `@ts-ignore` sprinkled where types are hard, _absence_ of `// HACK:` / `// XXX:` scars (real codebases have geology), stray `console.log` / `dd()` debug artifacts, and trivial boilerplate like `if (x) return true; else return false`.
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Rule Title Here
|
|
3
|
+
impact: CRITICAL|HIGH|MEDIUM
|
|
4
|
+
impactDescription: "Specific consequence — e.g., 'Makes code feel like a tutorial; reduces comprehension speed'"
|
|
5
|
+
tags: tag1, tag2, tag3
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Rule Title Here
|
|
9
|
+
|
|
10
|
+
**Impact: LEVEL (impactDescription)**
|
|
11
|
+
|
|
12
|
+
1-2 sentences explaining why this pattern is an AI fingerprint and why it hurts.
|
|
13
|
+
|
|
14
|
+
## Incorrect
|
|
15
|
+
|
|
16
|
+
```language
|
|
17
|
+
// ❌ AI-slop example
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**Why it's slop:**
|
|
21
|
+
|
|
22
|
+
- Reason 1
|
|
23
|
+
- Reason 2
|
|
24
|
+
|
|
25
|
+
## Correct
|
|
26
|
+
|
|
27
|
+
```language
|
|
28
|
+
// ✅ Human-equivalent
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Why it reads human:**
|
|
32
|
+
|
|
33
|
+
- Reason 1
|
|
34
|
+
- Reason 2
|
|
35
|
+
|
|
36
|
+
## Detection
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# grep / oxlint / mago invocation
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Reference: [Link](url) · Internal: [`related-rule`](related-rule.md)
|
package/build/Assets/Blueprints/skills/int-code-slop-review/rules/comments-closing-brace-labels.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Closing-Brace Labels
|
|
3
|
+
impact: MEDIUM
|
|
4
|
+
impactDescription: "Relic of older training corpora; clear AI fingerprint that modern editors make pointless"
|
|
5
|
+
tags: comments, closing-brace, ai-fingerprint, style
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Closing-Brace Labels
|
|
9
|
+
|
|
10
|
+
**Impact: MEDIUM (Relic of older training corpora; clear AI fingerprint that modern editors make pointless)**
|
|
11
|
+
|
|
12
|
+
`} // end function` / `} // end if block` / `} // close foreach` are a strong AI tell. The pattern comes from older C/COBOL/Verilog training data where blocks could span hundreds of lines and editors didn't fold scope. Modern PHP, TypeScript, and any editor with bracket-matching makes the label pure noise.
|
|
13
|
+
|
|
14
|
+
If your function is so long you need a label on its closing brace, the real fix is to split the function — not annotate the brace.
|
|
15
|
+
|
|
16
|
+
## Incorrect
|
|
17
|
+
|
|
18
|
+
```php
|
|
19
|
+
// ❌ Labels on closing braces
|
|
20
|
+
|
|
21
|
+
class OrderService
|
|
22
|
+
{
|
|
23
|
+
public function process(Order $order): void
|
|
24
|
+
{
|
|
25
|
+
if ($order->isPaid()) {
|
|
26
|
+
foreach ($order->items as $item) {
|
|
27
|
+
if ($item->requiresShipping()) {
|
|
28
|
+
$this->ship($item);
|
|
29
|
+
} // end if requiresShipping
|
|
30
|
+
} // end foreach items
|
|
31
|
+
} // end if isPaid
|
|
32
|
+
} // end function process
|
|
33
|
+
} // end class OrderService
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
// ❌ TS variant
|
|
38
|
+
function processOrder(order: Order): void {
|
|
39
|
+
if (order.isPaid()) {
|
|
40
|
+
order.items.forEach((item) => {
|
|
41
|
+
if (item.requiresShipping()) {
|
|
42
|
+
ship(item);
|
|
43
|
+
} // end if requiresShipping
|
|
44
|
+
}); // end forEach
|
|
45
|
+
} // end if isPaid
|
|
46
|
+
} // end function processOrder
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
**Why it's slop:**
|
|
50
|
+
|
|
51
|
+
- Every modern IDE highlights the matching opener when the cursor is on a brace
|
|
52
|
+
- The labels add bytes for zero information
|
|
53
|
+
- A function that needed labels for clarity is a function that needs to be split
|
|
54
|
+
- Pattern is recognisably training-data noise (PHP-from-2008, Verilog, COBOL)
|
|
55
|
+
|
|
56
|
+
## Correct
|
|
57
|
+
|
|
58
|
+
```php
|
|
59
|
+
// ✅ Either small enough not to need labels, OR split for clarity
|
|
60
|
+
|
|
61
|
+
class OrderService
|
|
62
|
+
{
|
|
63
|
+
public function process(Order $order): void
|
|
64
|
+
{
|
|
65
|
+
if (!$order->isPaid()) {
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
$this->shipEligibleItems($order);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
private function shipEligibleItems(Order $order): void
|
|
72
|
+
{
|
|
73
|
+
foreach ($order->items->filter->requiresShipping() as $item) {
|
|
74
|
+
$this->ship($item);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
// ✅ Smaller scopes, no labels needed
|
|
82
|
+
function processOrder(order: Order): void {
|
|
83
|
+
if (!order.isPaid()) return;
|
|
84
|
+
shipEligibleItems(order);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
function shipEligibleItems(order: Order): void {
|
|
88
|
+
order.items.filter((i) => i.requiresShipping()).forEach(ship);
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**Why it reads human:**
|
|
93
|
+
|
|
94
|
+
- Short functions; the closing brace is visually close to the opener
|
|
95
|
+
- No annotation noise; editor handles brace matching
|
|
96
|
+
- If a developer felt the need to label, they'd split the function instead
|
|
97
|
+
|
|
98
|
+
## Detection
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
# Closing brace followed by an "end" / function/class/if/foreach annotation comment
|
|
102
|
+
grep -rEn '^\s*\}\s*(\)\s*)?\s*(//|#).*\b(end|close|finish)\b' \
|
|
103
|
+
--include='*.php' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' \
|
|
104
|
+
app/ src/
|
|
105
|
+
|
|
106
|
+
# Specific PHP closing-tag labels
|
|
107
|
+
grep -rEn '^\s*\}\s*//.*(end (function|class|if|foreach|for|while|switch))' --include='*.php' app/
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
A single hit is borderline; **three or more in one file is an unmistakable AI fingerprint.**
|
|
111
|
+
|
|
112
|
+
Reference: [Code Complete — Chapter 32 on Self-Documenting Code](https://www.microsoftpressstore.com/store/code-complete-9780735619678) · Internal: [`comments-narration`](comments-narration.md)
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Empty Docblocks That Restate the Signature
|
|
3
|
+
impact: HIGH
|
|
4
|
+
impactDescription: "Adds bytes, zero information; suggests the author auto-generated without reading"
|
|
5
|
+
tags: comments, docblocks, jsdoc, phpdoc, ai-fingerprint
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Empty Docblocks That Restate the Signature
|
|
9
|
+
|
|
10
|
+
**Impact: HIGH (Adds bytes, zero information; suggests the author auto-generated without reading)**
|
|
11
|
+
|
|
12
|
+
A docblock that adds nothing the signature already says is a tell. `/** Get the user */` above `function getUser(): User` tells the reader nothing the function name and return type don't. Modern PHP and TypeScript both encode types in the signature; redundant docblocks are pure noise.
|
|
13
|
+
|
|
14
|
+
Useful docblocks document **edge cases, thrown exceptions, side effects, or non-obvious semantics** — not "this method does what its name says".
|
|
15
|
+
|
|
16
|
+
## Incorrect
|
|
17
|
+
|
|
18
|
+
```php
|
|
19
|
+
// ❌ Restates the signature; adds nothing
|
|
20
|
+
/**
|
|
21
|
+
* Get the user by ID.
|
|
22
|
+
*
|
|
23
|
+
* @param int $id The user ID
|
|
24
|
+
* @return User The user
|
|
25
|
+
*/
|
|
26
|
+
public function getUser(int $id): User
|
|
27
|
+
{
|
|
28
|
+
return User::findOrFail($id);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Adds two numbers together.
|
|
33
|
+
*
|
|
34
|
+
* @param int $a First number
|
|
35
|
+
* @param int $b Second number
|
|
36
|
+
* @return int The sum
|
|
37
|
+
*/
|
|
38
|
+
public function add(int $a, int $b): int
|
|
39
|
+
{
|
|
40
|
+
return $a + $b;
|
|
41
|
+
}
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
// ❌ Same pattern in TS
|
|
46
|
+
/**
|
|
47
|
+
* Get the user.
|
|
48
|
+
* @param id - The user ID
|
|
49
|
+
* @returns The user
|
|
50
|
+
*/
|
|
51
|
+
function getUser(id: string): User {
|
|
52
|
+
/* ... */
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Adds two numbers.
|
|
57
|
+
* @param a - First number
|
|
58
|
+
* @param b - Second number
|
|
59
|
+
* @returns The sum
|
|
60
|
+
*/
|
|
61
|
+
function add(a: number, b: number): number {
|
|
62
|
+
return a + b;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**Why it's slop:**
|
|
67
|
+
|
|
68
|
+
- The signature already says all of this — return type, parameter types, what's returned
|
|
69
|
+
- Bytes per useful info: ~zero
|
|
70
|
+
- A human writes a docblock when there's something the signature _can't_ express
|
|
71
|
+
|
|
72
|
+
## Correct — option 1: no docblock at all
|
|
73
|
+
|
|
74
|
+
```php
|
|
75
|
+
// ✅ Signature speaks for itself
|
|
76
|
+
public function getUser(int $id): User
|
|
77
|
+
{
|
|
78
|
+
return User::findOrFail($id);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public function add(int $a, int $b): int
|
|
82
|
+
{
|
|
83
|
+
return $a + $b;
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Correct — option 2: docblock that earns its place
|
|
88
|
+
|
|
89
|
+
```php
|
|
90
|
+
// ✅ Docblock documents what the signature CAN'T say
|
|
91
|
+
/**
|
|
92
|
+
* Get a user, or throw if not found.
|
|
93
|
+
*
|
|
94
|
+
* @throws ModelNotFoundException if no user matches $id
|
|
95
|
+
* @throws AuthorizationException if the current user can't view $id
|
|
96
|
+
*/
|
|
97
|
+
public function getUser(int $id): User
|
|
98
|
+
{
|
|
99
|
+
Gate::authorize('view', User::class);
|
|
100
|
+
return User::findOrFail($id);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```typescript
|
|
105
|
+
// ✅ TSDoc that documents real edge cases
|
|
106
|
+
/**
|
|
107
|
+
* @throws OutOfRangeError if `amount` exceeds the Stripe 999,999.99 cap.
|
|
108
|
+
* @remarks Rounds to 2 decimal places using banker's rounding.
|
|
109
|
+
*/
|
|
110
|
+
function formatAmountForStripe(amount: number): string {
|
|
111
|
+
/* ... */
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Why it reads human:**
|
|
116
|
+
|
|
117
|
+
- The remaining docblocks all carry information the signature can't
|
|
118
|
+
- A reader scanning the file sees docblocks and trusts they're load-bearing
|
|
119
|
+
|
|
120
|
+
## Detection
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Files with @param/@return docblocks
|
|
124
|
+
grep -rln '@param\|@return\|@returns' --include='*.php' app/
|
|
125
|
+
grep -rln '@param\|@returns' --include='*.ts' --include='*.tsx' src/
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Mago's `no-empty-comment` detects literally empty comments, and `valid-docblock` checks syntax. Neither establishes whether a non-empty docblock merely restates a signature; use manual review for that distinction.
|
|
129
|
+
|
|
130
|
+
The most reliable enforcement is a **PR review rule**: "every `@param` / `@return` must add information the signature doesn't already provide. Delete the rest."
|
|
131
|
+
|
|
132
|
+
Reference: [PHPDoc Tags Reference](https://docs.phpdoc.org/3.0/guide/references/phpdoc/tags/) · [TSDoc](https://tsdoc.org/) · [Mago no-empty-comment](https://mago.carthage.software/1.59.0/en/tools/linter/rules/#no-empty-comment) · [Mago valid-docblock](https://mago.carthage.software/1.59.0/en/tools/linter/rules/#valid-docblock) · Internal: [`comments-narration`](comments-narration.md)
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Narration Comments
|
|
3
|
+
impact: CRITICAL
|
|
4
|
+
impactDescription: "The single loudest AI tell; cuts reading speed and signals the author didn't read what they shipped"
|
|
5
|
+
tags: comments, narration, ai-fingerprint
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Narration Comments
|
|
9
|
+
|
|
10
|
+
**Impact: CRITICAL (The single loudest AI tell; cuts reading speed and signals the author didn't read what they shipped)**
|
|
11
|
+
|
|
12
|
+
Models love narrating the next line in a comment above it. The comment adds no information — it just restates the code in English. A reader has to read both, decide they say the same thing, and feel a tiny tax of distrust. Across a 500-line file, the tax compounds into "I have no idea what this codebase is doing."
|
|
13
|
+
|
|
14
|
+
A useful comment answers **why**, not **what**. If the code itself says _what_, the comment is noise.
|
|
15
|
+
|
|
16
|
+
## Incorrect
|
|
17
|
+
|
|
18
|
+
```php
|
|
19
|
+
// ❌ Comments narrate the next line — pure AI fingerprint
|
|
20
|
+
|
|
21
|
+
public function createUser(array $data): User
|
|
22
|
+
{
|
|
23
|
+
// Validate the input data
|
|
24
|
+
$validated = Validator::make($data, [...])->validate();
|
|
25
|
+
|
|
26
|
+
// Create a new user with the validated data
|
|
27
|
+
$user = User::create($validated);
|
|
28
|
+
|
|
29
|
+
// Send a welcome email to the user
|
|
30
|
+
Mail::to($user)->send(new WelcomeEmail($user));
|
|
31
|
+
|
|
32
|
+
// Return the newly created user
|
|
33
|
+
return $user;
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
// ❌ Same pattern in TS — every line narrated above
|
|
39
|
+
function calculateTotal(items: Item[]): number {
|
|
40
|
+
// Initialize the total to zero
|
|
41
|
+
let total = 0;
|
|
42
|
+
|
|
43
|
+
// Loop through each item in the items array
|
|
44
|
+
for (const item of items) {
|
|
45
|
+
// Add the item's price multiplied by quantity to the total
|
|
46
|
+
total += item.price * item.quantity;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Return the calculated total
|
|
50
|
+
return total;
|
|
51
|
+
}
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
**Why it's slop:**
|
|
55
|
+
|
|
56
|
+
- Every comment is a literal English translation of the code on the next line
|
|
57
|
+
- A reader's eyes have to traverse twice (comment → code) to learn nothing extra
|
|
58
|
+
- Suggests the author was thinking out loud rather than thinking ahead
|
|
59
|
+
- A human author who knew this code wouldn't bother writing these comments
|
|
60
|
+
|
|
61
|
+
## Correct
|
|
62
|
+
|
|
63
|
+
```php
|
|
64
|
+
// ✅ Comments removed (the code says what it does); explain WHY only if non-obvious
|
|
65
|
+
|
|
66
|
+
public function createUser(array $data): User
|
|
67
|
+
{
|
|
68
|
+
$validated = Validator::make($data, [...])->validate();
|
|
69
|
+
|
|
70
|
+
$user = User::create($validated);
|
|
71
|
+
Mail::to($user)->send(new WelcomeEmail($user));
|
|
72
|
+
|
|
73
|
+
return $user;
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
// ✅ Total comments removed; if any line needed comment, it'd be a WHY
|
|
79
|
+
function calculateTotal(items: Item[]): number {
|
|
80
|
+
return items.reduce((sum, i) => sum + i.price * i.quantity, 0);
|
|
81
|
+
}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
If a comment IS needed, it explains _why_:
|
|
85
|
+
|
|
86
|
+
```typescript
|
|
87
|
+
// ✅ Good comment — explains a hidden constraint
|
|
88
|
+
// Note: `total` is in cents (Stripe API uses integer minor units).
|
|
89
|
+
function calculateTotal(items: Item[]): number {
|
|
90
|
+
// Stripe rejects single charges > 999,999_99 cents (= $999,999.99). Cap to avoid charge failure.
|
|
91
|
+
const total = items.reduce((sum, i) => sum + i.price * i.quantity, 0);
|
|
92
|
+
return Math.min(total, 99_999_999); // 999,999.99 expressed in cents
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**Why it reads human:**
|
|
97
|
+
|
|
98
|
+
- Code speaks for itself; reader processes once
|
|
99
|
+
- The one remaining comment carries a _load-bearing_ piece of context (Stripe constraint) you couldn't infer from the code
|
|
100
|
+
- Signals the author understood the code well enough to know what didn't need explaining
|
|
101
|
+
|
|
102
|
+
## Detection
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# Heuristic: comments immediately followed by code that uses the comment's keyword
|
|
106
|
+
# (rough but effective — flags lines where the comment is one word-of-code below)
|
|
107
|
+
grep -rEn '^[[:space:]]*//.*' --include='*.ts' --include='*.tsx' --include='*.js' --include='*.jsx' src/ | head -50
|
|
108
|
+
grep -rEn '^[[:space:]]*//.*' --include='*.php' app/ | head -50
|
|
109
|
+
|
|
110
|
+
# Stronger heuristic: comment + next non-blank line share a keyword
|
|
111
|
+
# (run in code review tools or PHPStorm "Comment Density" inspections)
|
|
112
|
+
|
|
113
|
+
# Review comments with a team-level "comments answer WHY only" checklist.
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
There is no fully automatic linter for this — it requires a reviewer's judgement. The detection pattern is "does the comment translate, or add context?"
|
|
117
|
+
|
|
118
|
+
Reference: [Code Complete — Self-Documenting Code](https://www.microsoftpressstore.com/store/code-complete-9780735619678) · Internal: [`comments-empty-docblocks`](comments-empty-docblocks.md)
|