my 1st response to TLDR - Prompts don't scale. MCPs don't scale. Hooks do.
First of all, I don't really like concept of "Explanation" so I will be raw and show my code. Ask your LLM for detailed explanation if you need.
(and also I really don't like Reddit input panel for code sharing... don't allow me to share code)
How exactly does the hook "detect that the AI accessed the model directly?"
regexps (for now) to not to make iteration slow (AST is little heavy)
And also don't write by yourself, let AI do it when required
My approach is like "be stiff then extend"
How exactly do you force intent? Are you doing a blocking hook?
Yes, blocking - even some time just awareness blocking like at first read I give architecture to AI then allow the seconds read (like this experiences that forces AI to use my tool)
Hook in Action
Here is the one of the experience
noMagicNumber Rule
Here is code of it:
/**
* PURPOSE: Self-documenting code enforcement - named constants over magic numbers
* QUERY: "Bu satırda naked magic number var mı?"
* YIELDS: RuleCheckResult (violation if magic number found)
*/
import type { LineRule, LineRuleCheckParams, RuleCheckResult } from '../../types'
// QUERY: "Hangi sayılar ve pattern'ler hariç tutulur?"
const ALLOWED_NUMBERS = new Set([
0, 1, -1, 2, 10, 100, 1000,
// HTTP status codes
200, 201, 204, 301, 302, 304,
400, 401, 403, 404, 405, 409, 422, 429,
500, 502, 503, 504
])
export const noMagicNumberRule: LineRule = {
name: 'onMagicNumber',
active: true,
exclude: { paths: ['Config', 'Constants', 'Tests', 'rules/'], patterns: [] },
check(params: LineRuleCheckParams): RuleCheckResult {
// Skip constant declarations
if (params.trimmed.match(/^(static\s+)?(let|var)\s+[a-z][A-Za-z]*\s*[=:]/)) {
return { matched: false }
}
// Skip enum cases
if (params.trimmed.match(/case\s+\w+\s*=/)) {
return { matched: false }
}
// Remove string literals to avoid false positives in examples/templates
const withoutStrings = params.trimmed
.replace(/"[^"]*"/g, '""')
.replace(/"""[\s\S]*?"""/g, '""')
// Find standalone numbers (not part of identifiers)
// \d in lookbehind prevents matching substrings like "970" in "1970"
const numberMatches = withoutStrings.match(/(?<![A-Za-z_.\d])\d{2,}(?![A-Za-z_\d])/g)
if (numberMatches) {
for (const match of numberMatches) {
const num = parseInt(match, 10)
if (!ALLOWED_NUMBERS.has(num) && num > 10) {
return {
matched: true,
violation: generateViolation({ line: params.line, code: params.trimmed, number: match })
}
}
}
}
return { matched: false }
}
}
function generateViolation(params: { line: number; code: string; number: string }): string {
return `[swift] OnMagicNumber violation
Line: ${params.line}
Found magic number: ${params.number}
Code: ${params.code}
CONSTRAINT: Use named constants instead of magic numbers (or use *Config, *Constants)
CORRECT:
private let timeoutSeconds = 30
private let maxRetries = 3
static let secondsPerDay = 86400`
}TypeScript Examples
for now: I can share one of my typescript examples, these ones for DETERMINISM to catch mistakes BEFORE runtime
noHardcodedPath Rule
/**
* EVENT: OnHardcodedPath
* OUTCOME: Portable code - no machine-specific paths
*
* PATTERN: Use config or environment variables
* CONSTRAINT: Absolute paths like /Users/, C:\ forbidden
*/
import type { LineRule, LineRuleCheckParams, RuleCheckResult } from '../types'
export const noHardcodedPathRule: LineRule = {
name: 'onHardcodedPath',
active: true,
exclude: { paths: ['config.ts'], patterns: [] },
check(params: LineRuleCheckParams): RuleCheckResult {
const hardcodedPathPatterns = [
/['"`]\/Users\/\w+/,
/['"`]\/home\/\w+/,
/['"`]C:\\Users\\/i,
/['"`]\/var\/\w+/,
/['"`]\/tmp\/\w+/
]
for (const pattern of hardcodedPathPatterns) {
if (pattern.test(params.trimmed)) {
return {
matched: true,
violation: generateViolation({ line: params.line, code: params.trimmed })
}
}
}
return { matched: false }
}
}
function generateViolation(params: { line: number; code: string }): string {
return `[typescript] OnHardcodedPath violation
Line: ${params.line}
Found: ${params.code}
CONSTRAINT: Hardcoded paths forbidden
CORRECT:
import { homedir } from 'os'
const userDir = homedir()
// Or use config
const dataPath = config.dataDirectory`
}noNullUnion Rule
/**
* EVENT: OnNullUnion
* OUTCOME: Forced exhaustive handling - compile-time guarantee
*
* PATTERN: { type: 'success'; data: T } | { type: 'failed'; reason: string }
* CONSTRAINT: Union with null/undefined triggers violation
*
* CROSS-DOMAIN: Swift → OnForceUnwrap (same null-safety concern)
*/
import type { LineRule, LineRuleCheckParams, RuleCheckResult } from '../../types'
// MARK: - Rule
export const noNullUnionRule: LineRule = {
name: 'onNullUnion',
active: true,
exclude: { paths: ['types.ts'], patterns: [] },
check(params: LineRuleCheckParams): RuleCheckResult {
const nullUnionPattern = /:\s*\w+\s*\|\s*null/
const undefinedUnionPattern = /:\s*\w+\s*\|\s*undefined/
const nullFirstPattern = /:\s*null\s*\|\s*\w+/
const undefinedFirstPattern = /:\s*undefined\s*\|\s*\w+/
if (
nullUnionPattern.test(params.trimmed) ||
undefinedUnionPattern.test(params.trimmed) ||
nullFirstPattern.test(params.trimmed) ||
undefinedFirstPattern.test(params.trimmed)
) {
return {
matched: true,
violation: generateViolation({ line: params.line, code: params.trimmed })
}
}
return { matched: false }
}
}
// MARK: - Violation
function generateViolation(params: { line: number; code: string }): string {
return `[typescript] OnNullUnion violation
Line: ${params.line}
Found: ${params.code}
CONSTRAINT: Union with null or undefined forbidden
CONVENTION:
- type: veri/sonuc (ne oldu?) → { type: 'success' } | { type: 'failed' }
- intent: aksiyon/istek (ne yapmak istiyorsun?) → { intent: 'start' } | { intent: 'stop' }`
}Ask me more if you want to explore..
Last updated
Was this helpful?