@caoscompanybr/merlin 3.5.0
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/.claude/CLAUDE.md +216 -0
- package/.claude/hooks/README-license-gate.md +45 -0
- package/.claude/hooks/auto-summarize.js +47 -0
- package/.claude/hooks/context-monitor.js +60 -0
- package/.claude/hooks/doc-sync.js +111 -0
- package/.claude/hooks/license-gate.cjs +59 -0
- package/.claude/hooks/session-reset.js +27 -0
- package/.claude/hooks/thoughts-indexer.js +80 -0
- package/.claude/rules/merlin-constitution.md +27 -0
- package/.merlin-core/commands/README.md +19 -0
- package/.merlin-core/commands/founder-mode.md +51 -0
- package/.merlin-core/commands/git/commit.md +35 -0
- package/.merlin-core/commands/git/describe-pr.md +43 -0
- package/.merlin-core/commands/git/safe-commit.md +182 -0
- package/.merlin-core/commands/implementation/implement-plan.md +129 -0
- package/.merlin-core/commands/implementation/oneshot.md +63 -0
- package/.merlin-core/commands/implementation/tdd.md +152 -0
- package/.merlin-core/commands/planning/create-plan.md +184 -0
- package/.merlin-core/commands/planning/iterate-plan.md +45 -0
- package/.merlin-core/commands/planning/validate-plan.md +48 -0
- package/.merlin-core/commands/research/analyze-issue.md +155 -0
- package/.merlin-core/commands/research/research-codebase.md +157 -0
- package/.merlin-core/commands/review/adversarial-review.md +112 -0
- package/.merlin-core/commands/review/check.md +91 -0
- package/.merlin-core/commands/review/debug.md +135 -0
- package/.merlin-core/commands/review/doubts.md +178 -0
- package/.merlin-core/commands/review/engineering-audit.md +87 -0
- package/.merlin-core/commands/review/local-review.md +48 -0
- package/.merlin-core/commands/review/verify-goals.md +83 -0
- package/.merlin-core/commands/session/capture-feedback.md +74 -0
- package/.merlin-core/commands/session/capture-learning.md +155 -0
- package/.merlin-core/commands/session/check-objectives.md +85 -0
- package/.merlin-core/commands/session/conclude.md +125 -0
- package/.merlin-core/commands/session/create-handoff.md +88 -0
- package/.merlin-core/commands/session/create-objective.md +111 -0
- package/.merlin-core/commands/session/create-process.md +105 -0
- package/.merlin-core/commands/session/create-reminder.md +86 -0
- package/.merlin-core/commands/session/fast-start.md +261 -0
- package/.merlin-core/commands/session/recall-learnings.md +79 -0
- package/.merlin-core/commands/session/recall-processes.md +74 -0
- package/.merlin-core/commands/session/resume-handoff.md +51 -0
- package/.merlin-core/commands/session/run-process.md +53 -0
- package/.merlin-core/commands/special/beauty.md +89 -0
- package/.merlin-core/commands/special/common-ground.md +114 -0
- package/.merlin-core/commands/special/elicit.md +98 -0
- package/.merlin-core/commands/special/party.md +66 -0
- package/.merlin-core/commands/special/scrape.md +78 -0
- package/.merlin-core/commands/special/skill-audit.md +128 -0
- package/.merlin-core/commands/special/start-here.md +132 -0
- package/.merlin-core/constitution.md +442 -0
- package/.merlin-core/core/README.md +19 -0
- package/.merlin-core/core/alkimia/README.md +20 -0
- package/.merlin-core/core/alkimia/context/context-tracker.js +209 -0
- package/.merlin-core/core/alkimia/domain/domain-loader.js +215 -0
- package/.merlin-core/core/alkimia/engine.js +284 -0
- package/.merlin-core/core/alkimia/layers/l0-constitution.js +47 -0
- package/.merlin-core/core/alkimia/layers/l1-global.js +58 -0
- package/.merlin-core/core/alkimia/layers/l2-agent.js +58 -0
- package/.merlin-core/core/alkimia/layers/l3-workflow.js +54 -0
- package/.merlin-core/core/alkimia/layers/l4-task.js +45 -0
- package/.merlin-core/core/alkimia/layers/l5-squad.js +161 -0
- package/.merlin-core/core/alkimia/layers/l6-skill.js +520 -0
- package/.merlin-core/core/alkimia/layers/l7-star-command.js +87 -0
- package/.merlin-core/core/alkimia/layers/layer-processor.js +78 -0
- package/.merlin-core/core/alkimia/mandate.js +46 -0
- package/.merlin-core/core/alkimia/memory/doc-sync.js +201 -0
- package/.merlin-core/core/alkimia/memory/document-sharder.js +272 -0
- package/.merlin-core/core/alkimia/memory/git-history-retriever.js +225 -0
- package/.merlin-core/core/alkimia/memory/memory-bridge.js +97 -0
- package/.merlin-core/core/alkimia/memory/session-analyzer.js +400 -0
- package/.merlin-core/core/alkimia/memory/thoughts-indexer.js +477 -0
- package/.merlin-core/core/alkimia/memory/thoughts-provider.js +603 -0
- package/.merlin-core/core/alkimia/output/formatter.js +464 -0
- package/.merlin-core/core/alkimia/security/content-sanitizer.js +140 -0
- package/.merlin-core/core/alkimia/skill-importer.js +440 -0
- package/.merlin-core/core/alkimia/squads/default/.synapse/manifest +17 -0
- package/.merlin-core/core/alkimia/utils/frontmatter.js +321 -0
- package/.merlin-core/core/alkimia/utils/tokens.js +24 -0
- package/.merlin-core/core/approval/README.md +16 -0
- package/.merlin-core/core/approval/approval-engine.js +380 -0
- package/.merlin-core/core/approval/channels/cli-channel.js +50 -0
- package/.merlin-core/core/config/README.md +17 -0
- package/.merlin-core/core/config/config-cache.js +182 -0
- package/.merlin-core/core/config/config-loader.js +279 -0
- package/.merlin-core/core/config/config-resolver.js +411 -0
- package/.merlin-core/core/config/env-interpolator.js +123 -0
- package/.merlin-core/core/config/merge-utils.js +102 -0
- package/.merlin-core/core/config/schemas/core-config.schema.json +41 -0
- package/.merlin-core/core/config/schemas/framework-config.schema.json +24 -0
- package/.merlin-core/core/config/schemas/local-config.schema.json +23 -0
- package/.merlin-core/core/config/schemas/project-config.schema.json +189 -0
- package/.merlin-core/core/docs-consistency.js +140 -0
- package/.merlin-core/core/events/event-bus.js +344 -0
- package/.merlin-core/core/events/hook-handler.js +419 -0
- package/.merlin-core/core/execution/README.md +17 -0
- package/.merlin-core/core/execution/attempt-journal.js +380 -0
- package/.merlin-core/core/execution/autonomous-build-loop.js +637 -0
- package/.merlin-core/core/execution/build-orchestrator.js +296 -0
- package/.merlin-core/core/execution/build-state-manager.js +196 -0
- package/.merlin-core/core/execution/context-injector.js +204 -0
- package/.merlin-core/core/execution/cron-engine.js +247 -0
- package/.merlin-core/core/execution/cron-expression.js +148 -0
- package/.merlin-core/core/execution/env-preflight.js +423 -0
- package/.merlin-core/core/execution/guardrail-engine.js +745 -0
- package/.merlin-core/core/execution/heartbeat-engine.js +198 -0
- package/.merlin-core/core/execution/model-router.js +282 -0
- package/.merlin-core/core/execution/parallel-executor.js +378 -0
- package/.merlin-core/core/execution/parallel-monitor.js +201 -0
- package/.merlin-core/core/execution/party-session.js +311 -0
- package/.merlin-core/core/execution/rate-limit-manager.js +152 -0
- package/.merlin-core/core/execution/result-aggregator.js +215 -0
- package/.merlin-core/core/execution/semantic-merge-engine.js +320 -0
- package/.merlin-core/core/execution/subagent-dispatcher.js +721 -0
- package/.merlin-core/core/execution/success-verifier.js +227 -0
- package/.merlin-core/core/execution/task-metadata.js +105 -0
- package/.merlin-core/core/execution/team-executor.js +195 -0
- package/.merlin-core/core/execution/two-tier-editor.js +290 -0
- package/.merlin-core/core/execution/version-snapshot.js +294 -0
- package/.merlin-core/core/execution/wave-executor.js +224 -0
- package/.merlin-core/core/health-check/health-engine.js +415 -0
- package/.merlin-core/core/licensing/activation.js +281 -0
- package/.merlin-core/core/licensing/crc.js +103 -0
- package/.merlin-core/core/licensing/entitlement.js +99 -0
- package/.merlin-core/core/licensing/fingerprint.js +104 -0
- package/.merlin-core/core/licensing/gate.js +133 -0
- package/.merlin-core/core/licensing/hmac.js +42 -0
- package/.merlin-core/core/licensing/key.js +144 -0
- package/.merlin-core/core/licensing/license.js +212 -0
- package/.merlin-core/core/mcp/README.md +16 -0
- package/.merlin-core/core/mcp/browser-capability.js +191 -0
- package/.merlin-core/core/mcp/capability-mapper.js +92 -0
- package/.merlin-core/core/mcp/mcp-connector.js +278 -0
- package/.merlin-core/core/mcp/mcp-registry.js +101 -0
- package/.merlin-core/core/orchestration/README.md +17 -0
- package/.merlin-core/core/orchestration/agent-invoker.js +456 -0
- package/.merlin-core/core/orchestration/condition-evaluator.js +250 -0
- package/.merlin-core/core/orchestration/decision-tree.js +192 -0
- package/.merlin-core/core/orchestration/executor-assignment.js +372 -0
- package/.merlin-core/core/orchestration/gate-evaluator.js +653 -0
- package/.merlin-core/core/orchestration/intent-classifier.js +579 -0
- package/.merlin-core/core/orchestration/lock-manager.js +308 -0
- package/.merlin-core/core/orchestration/master-orchestrator.js +363 -0
- package/.merlin-core/core/orchestration/phase-tool-masks.js +194 -0
- package/.merlin-core/core/orchestration/recovery-handler.js +402 -0
- package/.merlin-core/core/orchestration/reflect-checkpoint.js +431 -0
- package/.merlin-core/core/orchestration/session-state.js +430 -0
- package/.merlin-core/core/orchestration/skill-dispatcher.js +255 -0
- package/.merlin-core/core/orchestration/step-loader.js +226 -0
- package/.merlin-core/core/orchestration/workflow-executor.js +864 -0
- package/.merlin-core/core/process/executor.js +231 -0
- package/.merlin-core/core/process/process-file.js +50 -0
- package/.merlin-core/core/process/secret-scan.js +86 -0
- package/.merlin-core/core/process/signature.js +77 -0
- package/.merlin-core/core/quality-gates/README.md +17 -0
- package/.merlin-core/core/quality-gates/layer1-precommit.js +110 -0
- package/.merlin-core/core/quality-gates/layer2-pr-automation.js +116 -0
- package/.merlin-core/core/quality-gates/layer3-human-review.js +133 -0
- package/.merlin-core/core/registry/service-registry.js +140 -0
- package/.merlin-core/core-config.yaml +159 -0
- package/.merlin-core/development/README.md +17 -0
- package/.merlin-core/development/agents/README.md +16 -0
- package/.merlin-core/development/agents/analyst.md +214 -0
- package/.merlin-core/development/agents/architect.md +166 -0
- package/.merlin-core/development/agents/data-engineer.md +154 -0
- package/.merlin-core/development/agents/dev.md +203 -0
- package/.merlin-core/development/agents/devops.md +236 -0
- package/.merlin-core/development/agents/grimorio.md +125 -0
- package/.merlin-core/development/agents/merlin-master.md +173 -0
- package/.merlin-core/development/agents/meta.md +190 -0
- package/.merlin-core/development/agents/pm.md +145 -0
- package/.merlin-core/development/agents/po.md +172 -0
- package/.merlin-core/development/agents/qa.md +275 -0
- package/.merlin-core/development/agents/researcher.md +218 -0
- package/.merlin-core/development/agents/scout.md +179 -0
- package/.merlin-core/development/agents/sm.md +148 -0
- package/.merlin-core/development/agents/ux.md +169 -0
- package/.merlin-core/development/agents/web-researcher.md +203 -0
- package/.merlin-core/development/checklists/adversarial-review-checklist.md +70 -0
- package/.merlin-core/development/checklists/operations-ci-checklist.md +40 -0
- package/.merlin-core/development/checklists/operations-deploy-checklist.md +54 -0
- package/.merlin-core/development/checklists/operations-publish-checklist.md +47 -0
- package/.merlin-core/development/checklists/source-verification-checklist.md +38 -0
- package/.merlin-core/development/templates/HEARTBEAT-template.md +46 -0
- package/.merlin-core/development/templates/ears-requirements-template.md +93 -0
- package/.merlin-core/development/templates/handoff-template.md +50 -0
- package/.merlin-core/development/templates/prd-template.md +62 -0
- package/.merlin-core/development/templates/research-template.md +53 -0
- package/.merlin-core/development/templates/spec-template.md +84 -0
- package/.merlin-core/development/workflows/brownfield-discovery.yaml +166 -0
- package/.merlin-core/development/workflows/brownfield-service.yaml +52 -0
- package/.merlin-core/development/workflows/development-cycle.yaml +57 -0
- package/.merlin-core/development/workflows/epic-orchestration.yaml +47 -0
- package/.merlin-core/development/workflows/folloni-funnel.yaml +177 -0
- package/.merlin-core/development/workflows/greenfield-fullstack.yaml +167 -0
- package/.merlin-core/development/workflows/greenfield-service.yaml +56 -0
- package/.merlin-core/development/workflows/qa-loop.yaml +115 -0
- package/.merlin-core/development/workflows/spec-pipeline.yaml +185 -0
- package/.merlin-core/development/workflows/steps/folloni-01-research.yaml +35 -0
- package/.merlin-core/development/workflows/steps/folloni-02-architecture.yaml +41 -0
- package/.merlin-core/development/workflows/steps/folloni-03-implementation.yaml +52 -0
- package/.merlin-core/development/workflows/story-development-cycle.yaml +67 -0
- package/.merlin-core/docs/GUIDE.md +413 -0
- package/.merlin-core/docs/merlin-commands-guide-pt.md +183 -0
- package/.merlin-core/framework-config.yaml +148 -0
- package/.merlin-core/hooks/README.md +16 -0
- package/.merlin-core/hooks/precompact-memory-flush.js +69 -0
- package/.merlin-core/hooks/pretooluse-remote-approve.js +113 -0
- package/.merlin-core/hooks/spikes/spike-b-hook.js +70 -0
- package/.merlin-core/hooks/spikes/spike-b-stub.js +70 -0
- package/.merlin-core/index.js +91 -0
- package/.merlin-core/local-config.yaml.template +31 -0
- package/.merlin-core/mcp-servers/lsp-bridge/index.js +397 -0
- package/.merlin-core/modules/scraping/module.json +23 -0
- package/.merlin-core/project-config.yaml +89 -0
- package/.merlin-core/schemas/README.md +18 -0
- package/.merlin-core/schemas/agent-hook-schema.json +152 -0
- package/.merlin-core/schemas/agent-schema.json +31 -0
- package/.merlin-core/schemas/command-schema.json +18 -0
- package/.merlin-core/schemas/feedback-schema.json +36 -0
- package/.merlin-core/schemas/handoff-schema.json +19 -0
- package/.merlin-core/schemas/learning-schema.json +51 -0
- package/.merlin-core/schemas/module.schema.json +124 -0
- package/.merlin-core/schemas/must-haves-schema.json +95 -0
- package/.merlin-core/schemas/objective-schema.json +23 -0
- package/.merlin-core/schemas/plan-schema.json +20 -0
- package/.merlin-core/schemas/process-schema.json +82 -0
- package/.merlin-core/schemas/reminder-schema.json +20 -0
- package/.merlin-core/schemas/skill-eval-schema.json +92 -0
- package/.merlin-core/schemas/skill-schema.json +77 -0
- package/.merlin-core/schemas/workflow-schema.json +38 -0
- package/.merlin-core/skills/README.md +16 -0
- package/.merlin-core/skills/domain/azure-cloud/SKILL.md +211 -0
- package/.merlin-core/skills/domain/azure-cloud/references/appinsights-instrumentation.md +63 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-compliance.md +99 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-cost-optimization.md +419 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-deploy.md +82 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-diagnostics.md +130 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-prepare.md +134 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-quotas.md +290 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-rbac.md +11 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-resource-lookup.md +97 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-resource-visualizer.md +178 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-storage.md +91 -0
- package/.merlin-core/skills/domain/azure-cloud/references/azure-validate.md +58 -0
- package/.merlin-core/skills/domain/azure-cloud/references/entra-app-registration.md +192 -0
- package/.merlin-core/skills/domain/browser-automation/SKILL.md +311 -0
- package/.merlin-core/skills/domain/browser-automation/references/agent-browser-skill.md +632 -0
- package/.merlin-core/skills/domain/browser-automation/references/authentication.md +308 -0
- package/.merlin-core/skills/domain/browser-automation/references/commands.md +266 -0
- package/.merlin-core/skills/domain/browser-automation/references/profiling.md +120 -0
- package/.merlin-core/skills/domain/browser-automation/references/proxy-support.md +194 -0
- package/.merlin-core/skills/domain/browser-automation/references/session-management.md +194 -0
- package/.merlin-core/skills/domain/browser-automation/references/snapshot-refs.md +196 -0
- package/.merlin-core/skills/domain/browser-automation/references/video-recording.md +173 -0
- package/.merlin-core/skills/domain/browser-automation/templates/authenticated-session.sh +105 -0
- package/.merlin-core/skills/domain/browser-automation/templates/capture-workflow.sh +69 -0
- package/.merlin-core/skills/domain/browser-automation/templates/form-automation.sh +62 -0
- package/.merlin-core/skills/domain/digital-marketing/SKILL.md +292 -0
- package/.merlin-core/skills/domain/digital-marketing/references/content-strategy.md +320 -0
- package/.merlin-core/skills/domain/digital-marketing/references/copy-formats.md +298 -0
- package/.merlin-core/skills/domain/digital-marketing/references/copy-methodology.md +180 -0
- package/.merlin-core/skills/domain/digital-marketing/references/email-sequences.md +135 -0
- package/.merlin-core/skills/domain/digital-marketing/references/launch-strategy.md +213 -0
- package/.merlin-core/skills/domain/digital-marketing/references/pricing-strategy.md +160 -0
- package/.merlin-core/skills/domain/digital-marketing/references/programmatic-seo.md +237 -0
- package/.merlin-core/skills/domain/digital-marketing/references/revops-lifecycle.md +170 -0
- package/.merlin-core/skills/domain/digital-marketing/references/revops-operations.md +167 -0
- package/.merlin-core/skills/domain/digital-marketing/references/schema-markup.md +190 -0
- package/.merlin-core/skills/domain/digital-marketing/references/strategy-frameworks.md +324 -0
- package/.merlin-core/skills/domain/digital-marketing/references/traffic-management.md +350 -0
- package/.merlin-core/skills/domain/expo-native-ui/SKILL.md +348 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/animations.md +220 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/api-routes.md +361 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/cicd-workflows.md +84 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/controls.md +266 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/data-fetching.md +553 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/deployment-stores.md +1353 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/deployment.md +183 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/dev-client.md +166 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/dom-components.md +410 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/form-sheet.md +253 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/gradients.md +117 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/icons.md +218 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/media.md +245 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/platform-native.md +75 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/route-structure.md +229 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/search.md +249 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/storage.md +121 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/tabs.md +433 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/tailwind-native.md +473 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/toolbar-and-headers.md +284 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/upgrading-guides.md +674 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/upgrading.md +127 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/visual-effects.md +199 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/webgpu-three.md +605 -0
- package/.merlin-core/skills/domain/expo-native-ui/references/zoom-transitions.md +161 -0
- package/.merlin-core/skills/domain/marketing-ops/SKILL.md +117 -0
- package/.merlin-core/skills/domain/marketing-ops/references/_index.md +78 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ad-creative/references/generative-tools.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ad-creative/references/platform-specs.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ad-creative.md +251 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads/references/ad-copy-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads/references/audience-targeting.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads/references/conversion-tracking.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads/references/platform-setup-checklists.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ads.md +322 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ai-seo/references/content-patterns.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ai-seo/references/content-types.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ai-seo/references/platform-ranking-factors.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/ai-seo.md +388 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/apple-specs.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/benchmarks.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/google-play-specs.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/report-template.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso/references/scoring-criteria.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/aso.md +316 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/co-marketing.md +305 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/community-marketing.md +169 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitor-profiling/references/templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitor-profiling/references/tool-reference.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitor-profiling.md +442 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitors/references/content-architecture.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitors/references/templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/competitors.md +281 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/content-strategy.md +16 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/directory-submissions/references/directory-list.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/directory-submissions/references/positioning-variations.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/directory-submissions/references/submission-tracker-template.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/directory-submissions.md +396 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/free-tools/references/tool-types.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/free-tools.md +196 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/image/references/ai-image-prompting.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/image.md +352 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/launch.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/lead-magnets/references/benchmarks.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/lead-magnets/references/format-guide.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/lead-magnets.md +333 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/programmatic-seo.md +16 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/schema.md +16 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/seo-audit/references/ai-writing-detection.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/seo-audit/references/international-seo.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/seo-audit.md +546 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/site-architecture/references/mermaid-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/site-architecture/references/navigation-patterns.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/site-architecture/references/site-type-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/site-architecture.md +371 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/platform-limits.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/platforms.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/post-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/reverse-engineering.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social/references/short-form-video.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/social.md +431 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/video/references/ai-video-prompting.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/acquire/video.md +353 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/ab-testing/references/sample-size-guide.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/ab-testing/references/test-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/ab-testing.md +379 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/analytics/references/event-library.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/analytics/references/ga4-implementation.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/analytics/references/gtm-implementation.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/analytics.md +323 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/copy-editing.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/copywriting.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/cro/references/experiments.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/cro/references/form.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/cro.md +211 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/emails.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/paywalls/references/experiments.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/paywalls.md +255 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/popups.md +518 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/pricing.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement/references/deck-frameworks.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement/references/demo-scripts.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement/references/objection-library.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement/references/one-pager-templates.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/sales-enablement.md +371 -0
- package/.merlin-core/skills/domain/marketing-ops/references/activate/signup.md +406 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/co-marketing.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/community-marketing.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/referrals/references/affiliate-programs.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/referrals/references/program-examples.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/expand/referrals.md +278 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/customer-research/references/source-guides.md +425 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/customer-research.md +284 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/marketing-ideas/references/ideas-by-category.md +216 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/marketing-ideas.md +188 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/marketing-psychology.md +532 -0
- package/.merlin-core/skills/domain/marketing-ops/references/foundation/product-marketing.md +276 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/churn-prevention/references/cancel-flow-patterns.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/churn-prevention/references/dunning-playbook.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/churn-prevention.md +442 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/onboarding/references/experiments.md +19 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/onboarding.md +243 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/revops-lifecycle.md +18 -0
- package/.merlin-core/skills/domain/marketing-ops/references/retain/revops-operations.md +18 -0
- package/.merlin-core/skills/domain/n8n-automation/SKILL.md +149 -0
- package/.merlin-core/skills/domain/n8n-automation/references/code-javascript.md +3744 -0
- package/.merlin-core/skills/domain/n8n-automation/references/code-python.md +3293 -0
- package/.merlin-core/skills/domain/n8n-automation/references/expression-syntax.md +1662 -0
- package/.merlin-core/skills/domain/n8n-automation/references/mcp-tools-expert.md +2111 -0
- package/.merlin-core/skills/domain/n8n-automation/references/node-configuration.md +2523 -0
- package/.merlin-core/skills/domain/n8n-automation/references/validation-expert.md +2491 -0
- package/.merlin-core/skills/domain/n8n-automation/references/workflow-patterns.md +4624 -0
- package/.merlin-core/skills/domain/ops-manual/SKILL.md +225 -0
- package/.merlin-core/skills/domain/ops-manual/references/elicitation-questions.md +141 -0
- package/.merlin-core/skills/domain/ops-manual/references/external-skills-registry.md +63 -0
- package/.merlin-core/skills/domain/ops-manual/references/operations-template.yaml +132 -0
- package/.merlin-core/skills/domain/remotion-best-practices/SKILL.md +99 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/3d.md +86 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/animations.md +27 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/assets/charts-bar-chart.tsx +173 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/assets/text-animations-typewriter.tsx +100 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/assets/text-animations-word-highlight.tsx +108 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/assets.md +78 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/audio.md +172 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/calculate-metadata.md +131 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/can-decode.md +75 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/charts.md +68 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/compositions.md +154 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/display-captions.md +126 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/extract-frames.md +229 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/fonts.md +152 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/get-audio-duration.md +58 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/get-video-dimensions.md +68 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/get-video-duration.md +58 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/gifs.md +144 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/images.md +134 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/import-srt-captions.md +67 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/lottie.md +70 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/maps.md +414 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/measuring-dom-nodes.md +34 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/measuring-text.md +143 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/parameters.md +109 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/sequencing.md +118 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/tailwind.md +11 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/text-animations.md +20 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/timing.md +179 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/transcribe-captions.md +19 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/transitions.md +137 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/transparent-videos.md +106 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/trimming.md +51 -0
- package/.merlin-core/skills/domain/remotion-best-practices/rules/videos.md +171 -0
- package/.merlin-core/skills/domain/resend-email/SKILL.md +377 -0
- package/.merlin-core/skills/general/adversarial-review/SKILL.md +144 -0
- package/.merlin-core/skills/general/api-design/SKILL.md +513 -0
- package/.merlin-core/skills/general/apify-scrape/SKILL.md +137 -0
- package/.merlin-core/skills/general/apify-scrape/scripts/apify-scrape.sh +68 -0
- package/.merlin-core/skills/general/backup/SKILL.md +87 -0
- package/.merlin-core/skills/general/blkskrn/SKILL.md +392 -0
- package/.merlin-core/skills/general/blkskrn/references/animation-patterns.md +521 -0
- package/.merlin-core/skills/general/blkskrn/references/design-system.md +637 -0
- package/.merlin-core/skills/general/blkskrn/references/html-templates.md +440 -0
- package/.merlin-core/skills/general/blkskrn/references/presenter-template.md +45 -0
- package/.merlin-core/skills/general/blkskrn/references/slide-types.md +424 -0
- package/.merlin-core/skills/general/blkskrn/scripts/canvas-manager.js +502 -0
- package/.merlin-core/skills/general/blkskrn/scripts/presenter.js +90 -0
- package/.merlin-core/skills/general/blkskrn/templates/presenter.html +273 -0
- package/.merlin-core/skills/general/blkskrn/templates/slide-base.html +277 -0
- package/.merlin-core/skills/general/blkskrn/templates/viewer.html +165 -0
- package/.merlin-core/skills/general/browser-takeover/SKILL.md +53 -0
- package/.merlin-core/skills/general/claude-api/SKILL.md +90 -0
- package/.merlin-core/skills/general/code-javascript/SKILL.md +268 -0
- package/.merlin-core/skills/general/code-python/SKILL.md +424 -0
- package/.merlin-core/skills/general/code-style/SKILL.md +97 -0
- package/.merlin-core/skills/general/code-typescript/SKILL.md +361 -0
- package/.merlin-core/skills/general/cold-email/SKILL.md +164 -0
- package/.merlin-core/skills/general/cold-email/references/benchmarks.md +18 -0
- package/.merlin-core/skills/general/cold-email/references/follow-up-sequences.md +18 -0
- package/.merlin-core/skills/general/cold-email/references/frameworks.md +18 -0
- package/.merlin-core/skills/general/cold-email/references/personalization.md +18 -0
- package/.merlin-core/skills/general/cold-email/references/subject-lines.md +18 -0
- package/.merlin-core/skills/general/container-security/SKILL.md +462 -0
- package/.merlin-core/skills/general/context-management/SKILL.md +79 -0
- package/.merlin-core/skills/general/copy-editing/SKILL.md +501 -0
- package/.merlin-core/skills/general/copy-editing/references/checklist.md +18 -0
- package/.merlin-core/skills/general/copy-editing/references/content-refresh.md +18 -0
- package/.merlin-core/skills/general/copy-editing/references/plain-english-alternatives.md +18 -0
- package/.merlin-core/skills/general/copywriting/SKILL.md +294 -0
- package/.merlin-core/skills/general/copywriting/references/copy-frameworks.md +392 -0
- package/.merlin-core/skills/general/copywriting/references/natural-transitions.md +276 -0
- package/.merlin-core/skills/general/database/SKILL.md +561 -0
- package/.merlin-core/skills/general/database/references/postgres-concurrency.md +182 -0
- package/.merlin-core/skills/general/database/references/postgres-connections.md +97 -0
- package/.merlin-core/skills/general/database/references/postgres-data-patterns.md +159 -0
- package/.merlin-core/skills/general/database/references/postgres-monitoring.md +136 -0
- package/.merlin-core/skills/general/database/references/postgres-rls.md +140 -0
- package/.merlin-core/skills/general/database-provision/SKILL.md +56 -0
- package/.merlin-core/skills/general/deploy/SKILL.md +65 -0
- package/.merlin-core/skills/general/design-inspiration/SKILL.md +146 -0
- package/.merlin-core/skills/general/design-palette/SKILL.md +99 -0
- package/.merlin-core/skills/general/design-palette/references/full-palettes.md +144 -0
- package/.merlin-core/skills/general/design-system/SKILL.md +94 -0
- package/.merlin-core/skills/general/design-typography/SKILL.md +115 -0
- package/.merlin-core/skills/general/design-typography/references/full-pairings.md +144 -0
- package/.merlin-core/skills/general/design-ux-patterns/SKILL.md +155 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/charts-data-guidelines.md +197 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/landing-patterns.md +199 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/professional-ui-checklist.md +56 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/style-catalog.md +89 -0
- package/.merlin-core/skills/general/design-ux-patterns/references/ux-guidelines.md +837 -0
- package/.merlin-core/skills/general/discover-cloud/SKILL.md +108 -0
- package/.merlin-core/skills/general/doc-sync/SKILL.md +52 -0
- package/.merlin-core/skills/general/document-sharding/SKILL.md +53 -0
- package/.merlin-core/skills/general/docx/SKILL.md +418 -0
- package/.merlin-core/skills/general/docx/references/windows-setup.md +27 -0
- package/.merlin-core/skills/general/docx/scripts/__init__.py +1 -0
- package/.merlin-core/skills/general/docx/scripts/accept_changes.py +135 -0
- package/.merlin-core/skills/general/docx/scripts/comment.py +318 -0
- package/.merlin-core/skills/general/docx/scripts/office/__init__.py +0 -0
- package/.merlin-core/skills/general/docx/scripts/office/helpers/__init__.py +0 -0
- package/.merlin-core/skills/general/docx/scripts/office/helpers/merge_runs.py +199 -0
- package/.merlin-core/skills/general/docx/scripts/office/helpers/simplify_redlines.py +197 -0
- package/.merlin-core/skills/general/docx/scripts/office/pack.py +159 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chart.xsd +1499 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-chartDrawing.xsd +146 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-diagram.xsd +1085 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-lockedCanvas.xsd +11 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-main.xsd +3081 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-picture.xsd +23 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-spreadsheetDrawing.xsd +185 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/dml-wordprocessingDrawing.xsd +287 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/pml.xsd +1676 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-additionalCharacteristics.xsd +28 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-bibliography.xsd +144 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-commonSimpleTypes.xsd +174 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlDataProperties.xsd +25 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-customXmlSchemaProperties.xsd +18 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesCustom.xsd +59 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesExtended.xsd +56 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-documentPropertiesVariantTypes.xsd +195 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-math.xsd +582 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/shared-relationshipReference.xsd +25 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/sml.xsd +4439 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-main.xsd +570 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-officeDrawing.xsd +509 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-presentationDrawing.xsd +12 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-spreadsheetDrawing.xsd +108 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/vml-wordprocessingDrawing.xsd +96 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/wml.xsd +3646 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ISO-IEC29500-4_2016/xml.xsd +116 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ecma/fouth-edition/opc-contentTypes.xsd +42 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ecma/fouth-edition/opc-coreProperties.xsd +50 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ecma/fouth-edition/opc-digSig.xsd +49 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/ecma/fouth-edition/opc-relationships.xsd +33 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/mce/mc.xsd +75 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-2010.xsd +560 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-2012.xsd +67 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-2018.xsd +14 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-cex-2018.xsd +20 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-cid-2016.xsd +13 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-sdtdatahash-2020.xsd +4 -0
- package/.merlin-core/skills/general/docx/scripts/office/schemas/microsoft/wml-symex-2015.xsd +8 -0
- package/.merlin-core/skills/general/docx/scripts/office/soffice.py +183 -0
- package/.merlin-core/skills/general/docx/scripts/office/unpack.py +132 -0
- package/.merlin-core/skills/general/docx/scripts/office/validate.py +111 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/__init__.py +15 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/base.py +847 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/docx.py +446 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/pptx.py +275 -0
- package/.merlin-core/skills/general/docx/scripts/office/validators/redlining.py +247 -0
- package/.merlin-core/skills/general/docx/scripts/templates/comments.xml +3 -0
- package/.merlin-core/skills/general/docx/scripts/templates/commentsExtended.xml +3 -0
- package/.merlin-core/skills/general/docx/scripts/templates/commentsExtensible.xml +3 -0
- package/.merlin-core/skills/general/docx/scripts/templates/commentsIds.xml +3 -0
- package/.merlin-core/skills/general/docx/scripts/templates/people.xml +3 -0
- package/.merlin-core/skills/general/elicitation/SKILL.md +188 -0
- package/.merlin-core/skills/general/engineering-audit/SKILL.md +122 -0
- package/.merlin-core/skills/general/find-and-edit/SKILL.md +102 -0
- package/.merlin-core/skills/general/first-party-docs/SKILL.md +51 -0
- package/.merlin-core/skills/general/frontend-design/SKILL.md +204 -0
- package/.merlin-core/skills/general/guardrails/SKILL.md +144 -0
- package/.merlin-core/skills/general/image-gen/SKILL.md +49 -0
- package/.merlin-core/skills/general/learning-capture/SKILL.md +192 -0
- package/.merlin-core/skills/general/lgpd-compliance-audit/SKILL.md +448 -0
- package/.merlin-core/skills/general/load-testing/SKILL.md +114 -0
- package/.merlin-core/skills/general/load-testing/docker/Dockerfile.dashboard +21 -0
- package/.merlin-core/skills/general/load-testing/docker/docker-compose.locust.yml +39 -0
- package/.merlin-core/skills/general/load-testing/requirements.txt +1 -0
- package/.merlin-core/skills/general/load-testing/scripts/compare_baseline.py +172 -0
- package/.merlin-core/skills/general/load-testing/scripts/run_local.py +245 -0
- package/.merlin-core/skills/general/load-testing/templates/load_shape_stepped.py +35 -0
- package/.merlin-core/skills/general/load-testing/templates/locustfile_dashboard.py +47 -0
- package/.merlin-core/skills/general/load-testing/templates/threshold_hook.py +36 -0
- package/.merlin-core/skills/general/mage-beauty/SKILL.md +89 -0
- package/.merlin-core/skills/general/mage-beauty/references/anti-patterns.md +148 -0
- package/.merlin-core/skills/general/mage-beauty/references/color-and-contrast.md +87 -0
- package/.merlin-core/skills/general/mage-beauty/references/interaction-design.md +99 -0
- package/.merlin-core/skills/general/mage-beauty/references/motion-design.md +90 -0
- package/.merlin-core/skills/general/mage-beauty/references/remotion-bridge.md +187 -0
- package/.merlin-core/skills/general/mage-beauty/references/responsive-and-multi-format.md +98 -0
- package/.merlin-core/skills/general/mage-beauty/references/spatial-design.md +88 -0
- package/.merlin-core/skills/general/mage-beauty/references/typography.md +60 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-adapt.md +102 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-animate.md +97 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-audit.md +99 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-bolder.md +94 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-cinematic.md +128 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-clarify.md +107 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-colorize.md +106 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-critique.md +88 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-delight.md +98 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-distill.md +97 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-harden.md +79 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-layout.md +104 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-onboard.md +98 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-optimize.md +124 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-overdrive.md +105 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-polish.md +91 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-quieter.md +95 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-rebrand.md +127 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-shape.md +160 -0
- package/.merlin-core/skills/general/mage-beauty/references/verb-typeset.md +109 -0
- package/.merlin-core/skills/general/mage-beauty/references/voice-and-microcopy.md +137 -0
- package/.merlin-core/skills/general/mcp-builder/SKILL.md +92 -0
- package/.merlin-core/skills/general/network-debug/SKILL.md +51 -0
- package/.merlin-core/skills/general/next-best-practices/SKILL.md +177 -0
- package/.merlin-core/skills/general/next-best-practices/references/async-patterns.md +87 -0
- package/.merlin-core/skills/general/next-best-practices/references/bundling.md +182 -0
- package/.merlin-core/skills/general/next-best-practices/references/data-patterns.md +306 -0
- package/.merlin-core/skills/general/next-best-practices/references/debug-tricks.md +125 -0
- package/.merlin-core/skills/general/next-best-practices/references/directives.md +74 -0
- package/.merlin-core/skills/general/next-best-practices/references/error-handling.md +232 -0
- package/.merlin-core/skills/general/next-best-practices/references/file-conventions.md +141 -0
- package/.merlin-core/skills/general/next-best-practices/references/font.md +257 -0
- package/.merlin-core/skills/general/next-best-practices/references/functions.md +108 -0
- package/.merlin-core/skills/general/next-best-practices/references/hydration-error.md +88 -0
- package/.merlin-core/skills/general/next-best-practices/references/image.md +179 -0
- package/.merlin-core/skills/general/next-best-practices/references/metadata.md +296 -0
- package/.merlin-core/skills/general/next-best-practices/references/parallel-routes.md +298 -0
- package/.merlin-core/skills/general/next-best-practices/references/route-handlers.md +146 -0
- package/.merlin-core/skills/general/next-best-practices/references/rsc-boundaries.md +164 -0
- package/.merlin-core/skills/general/next-best-practices/references/runtime-selection.md +40 -0
- package/.merlin-core/skills/general/next-best-practices/references/scripts.md +141 -0
- package/.merlin-core/skills/general/next-best-practices/references/self-hosting.md +384 -0
- package/.merlin-core/skills/general/next-best-practices/references/suspense-boundaries.md +67 -0
- package/.merlin-core/skills/general/next-steps/SKILL.md +43 -0
- package/.merlin-core/skills/general/party-mode/SKILL.md +57 -0
- package/.merlin-core/skills/general/pdf/SKILL.md +298 -0
- package/.merlin-core/skills/general/pdf/references/forms.md +312 -0
- package/.merlin-core/skills/general/pdf/references/reference.md +640 -0
- package/.merlin-core/skills/general/pdf/references/windows-setup.md +40 -0
- package/.merlin-core/skills/general/pdf/scripts/check_bounding_boxes.py +65 -0
- package/.merlin-core/skills/general/pdf/scripts/check_fillable_fields.py +11 -0
- package/.merlin-core/skills/general/pdf/scripts/convert_pdf_to_images.py +33 -0
- package/.merlin-core/skills/general/pdf/scripts/create_validation_image.py +37 -0
- package/.merlin-core/skills/general/pdf/scripts/extract_form_field_info.py +122 -0
- package/.merlin-core/skills/general/pdf/scripts/extract_form_structure.py +115 -0
- package/.merlin-core/skills/general/pdf/scripts/fill_fillable_fields.py +98 -0
- package/.merlin-core/skills/general/pdf/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/.merlin-core/skills/general/pptx/SKILL.md +133 -0
- package/.merlin-core/skills/general/pptx/references/editing.md +213 -0
- package/.merlin-core/skills/general/pptx/references/pptxgenjs.md +581 -0
- package/.merlin-core/skills/general/pptx/references/windows-setup.md +27 -0
- package/.merlin-core/skills/general/pptx/scripts/__init__.py +0 -0
- package/.merlin-core/skills/general/pptx/scripts/add_slide.py +195 -0
- package/.merlin-core/skills/general/pptx/scripts/clean.py +286 -0
- package/.merlin-core/skills/general/pptx/scripts/thumbnail.py +289 -0
- package/.merlin-core/skills/general/property-testing/SKILL.md +214 -0
- package/.merlin-core/skills/general/purge-leaked-secret/SKILL.md +383 -0
- package/.merlin-core/skills/general/reflection/SKILL.md +100 -0
- package/.merlin-core/skills/general/secret-safe-commit/SKILL.md +246 -0
- package/.merlin-core/skills/general/secret-safe-commit/templates/.gitleaks.toml +91 -0
- package/.merlin-core/skills/general/secret-safe-commit/templates/.pre-commit-config.yaml +57 -0
- package/.merlin-core/skills/general/secret-safe-commit/templates/secret-scan.yml +48 -0
- package/.merlin-core/skills/general/semantic-search/SKILL.md +79 -0
- package/.merlin-core/skills/general/skill-creator/SKILL.md +342 -0
- package/.merlin-core/skills/general/skill-creator/agents/analyzer.md +283 -0
- package/.merlin-core/skills/general/skill-creator/agents/comparator.md +211 -0
- package/.merlin-core/skills/general/skill-creator/agents/grader.md +227 -0
- package/.merlin-core/skills/general/skill-creator/assets/eval_review.html +146 -0
- package/.merlin-core/skills/general/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.merlin-core/skills/general/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.merlin-core/skills/general/skill-creator/references/schemas.md +439 -0
- package/.merlin-core/skills/general/skill-creator/scripts/__init__.py +0 -0
- package/.merlin-core/skills/general/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.merlin-core/skills/general/skill-creator/scripts/generate_report.py +326 -0
- package/.merlin-core/skills/general/skill-creator/scripts/improve_description.py +247 -0
- package/.merlin-core/skills/general/skill-creator/scripts/package_skill.py +136 -0
- package/.merlin-core/skills/general/skill-creator/scripts/quick_validate.py +103 -0
- package/.merlin-core/skills/general/skill-creator/scripts/run_eval.py +310 -0
- package/.merlin-core/skills/general/skill-creator/scripts/run_loop.py +328 -0
- package/.merlin-core/skills/general/skill-creator/scripts/utils.py +47 -0
- package/.merlin-core/skills/general/start-here/SKILL.md +63 -0
- package/.merlin-core/skills/general/start-here/recipes.json +758 -0
- package/.merlin-core/skills/general/start-here/recipes.schema.json +57 -0
- package/.merlin-core/skills/general/static-analysis/SKILL.md +151 -0
- package/.merlin-core/skills/general/tailwind-design-system/SKILL.md +201 -0
- package/.merlin-core/skills/general/tailwind-design-system/references/advanced-v4.md +152 -0
- package/.merlin-core/skills/general/tailwind-design-system/references/component-patterns.md +353 -0
- package/.merlin-core/skills/general/teach-method/SKILL.md +86 -0
- package/.merlin-core/skills/general/team-execution/SKILL.md +67 -0
- package/.merlin-core/skills/general/testing/SKILL.md +412 -0
- package/.merlin-core/skills/general/token-economy/SKILL.md +55 -0
- package/.merlin-core/skills/general/vps-security-hardening/SKILL.md +406 -0
- package/.merlin-core/skills/general/web-quality/SKILL.md +180 -0
- package/.merlin-core/skills/general/webapp-testing/SKILL.md +153 -0
- package/.merlin-core/skills/general/webapp-testing/scripts/screenshot_compare.py +72 -0
- package/.merlin-core/skills/general/webapp-testing/scripts/with_server.py +103 -0
- package/.merlin-core/skills/general/xlsx/SKILL.md +167 -0
- package/.merlin-core/skills/general/xlsx/references/nodejs-sheetjs-styled-reports.md +141 -0
- package/.merlin-core/skills/general/xlsx/references/windows-setup.md +17 -0
- package/.merlin-core/skills/general/xlsx/scripts/recalc.py +184 -0
- package/.merlin-core/skills/general/xlsx/scripts/styled-report.js +130 -0
- package/.merlin-core/skills/general/yolo-mode/SKILL.md +60 -0
- package/.merlin-core/skills/general/youtube-transcript/SKILL.md +177 -0
- package/.merlin-core/skills/general/youtube-transcript/scripts/fetch_transcript.py +188 -0
- package/.merlin-core/skills/general/youtube-transcript/scripts/gladia_transcribe.mjs +230 -0
- package/.merlin-core/tools/commands/activate.js +72 -0
- package/.merlin-core/tools/commands/archive-thoughts.js +181 -0
- package/.merlin-core/tools/commands/backup.js +156 -0
- package/.merlin-core/tools/commands/certify-process.js +196 -0
- package/.merlin-core/tools/commands/convert.js +87 -0
- package/.merlin-core/tools/commands/cron.js +147 -0
- package/.merlin-core/tools/commands/disable.js +73 -0
- package/.merlin-core/tools/commands/doc-sync.js +127 -0
- package/.merlin-core/tools/commands/eval-skill.js +193 -0
- package/.merlin-core/tools/commands/frontmatter.js +49 -0
- package/.merlin-core/tools/commands/heartbeat.js +43 -0
- package/.merlin-core/tools/commands/index-thoughts.js +35 -0
- package/.merlin-core/tools/commands/install-remote-approve.js +184 -0
- package/.merlin-core/tools/commands/install.js +81 -0
- package/.merlin-core/tools/commands/lib/__verify__/diff-reports.js +170 -0
- package/.merlin-core/tools/commands/lib/fs-safe.js +186 -0
- package/.merlin-core/tools/commands/lib/preflight.js +607 -0
- package/.merlin-core/tools/commands/lib/preserve.js +232 -0
- package/.merlin-core/tools/commands/lib/project-config.template.yaml +69 -0
- package/.merlin-core/tools/commands/lib/report.js +231 -0
- package/.merlin-core/tools/commands/lib/settings-merge.js +134 -0
- package/.merlin-core/tools/commands/license.js +52 -0
- package/.merlin-core/tools/commands/list.js +125 -0
- package/.merlin-core/tools/commands/migrate-alkimia.js +271 -0
- package/.merlin-core/tools/commands/modules.js +68 -0
- package/.merlin-core/tools/commands/provision.js +83 -0
- package/.merlin-core/tools/commands/prune-feedback.js +114 -0
- package/.merlin-core/tools/commands/run-process.js +28 -0
- package/.merlin-core/tools/commands/state.js +79 -0
- package/.merlin-core/tools/commands/sync-bridges.js +197 -0
- package/.merlin-core/tools/commands/upgrade.js +1135 -0
- package/.merlin-core/tools/commands/validate-recipes.js +218 -0
- package/.merlin-core/tools/commands/validate.js +159 -0
- package/.merlin-core/tools/commands/yolo.js +82 -0
- package/.merlin-core/tools/compose-rules.mjs +179 -0
- package/.merlin-core/tools/disable-module.mjs +150 -0
- package/.merlin-core/tools/lib/deployer.mjs +131 -0
- package/.merlin-core/tools/lib/modules-activation.mjs +225 -0
- package/.merlin-core/tools/merlin-tools.js +153 -0
- package/.merlin-core/tools/migrate-frontmatter-v3.js +192 -0
- package/.merlin-core/tools/modules-catalog.mjs +174 -0
- package/.merlin-core/tools/provision-module.mjs +191 -0
- package/.merlin-core/tools/verify-module.mjs +99 -0
- package/.merlin-core/tools/vps-security-audit.sh +234 -0
- package/INSTALL.md +312 -0
- package/LICENSE +118 -0
- package/PRIVACY-LICENSING.md +65 -0
- package/README.md +391 -0
- package/bin/README.md +15 -0
- package/bin/convert-to-merlin.sh +109 -0
- package/bin/fleet-patch-hooks.sh +144 -0
- package/bin/fleet-patch-v3-fixes.sh +127 -0
- package/bin/merlin-init.js +232 -0
- package/bin/merlin.js +321 -0
- package/package.json +127 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# PostgreSQL Concurrency & Locking
|
|
2
|
+
|
|
3
|
+
Patterns for safe concurrent access: advisory locks, deadlock prevention, transaction discipline, and queue processing with SKIP LOCKED.
|
|
4
|
+
|
|
5
|
+
## Advisory Locks
|
|
6
|
+
|
|
7
|
+
Application-level coordination without requiring database rows to lock on. Useful for singleton processes, report generation, and resource coordination.
|
|
8
|
+
|
|
9
|
+
**Incorrect (creating rows just for locking):**
|
|
10
|
+
|
|
11
|
+
```sql
|
|
12
|
+
CREATE TABLE resource_locks (resource_name TEXT PRIMARY KEY);
|
|
13
|
+
INSERT INTO resource_locks VALUES ('report_generator');
|
|
14
|
+
SELECT * FROM resource_locks WHERE resource_name = 'report_generator' FOR UPDATE;
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
**Correct (advisory locks — no table needed):**
|
|
18
|
+
|
|
19
|
+
```sql
|
|
20
|
+
-- Session-level lock (released on disconnect or explicit unlock)
|
|
21
|
+
SELECT pg_advisory_lock(hashtext('report_generator'));
|
|
22
|
+
-- ... do exclusive work ...
|
|
23
|
+
SELECT pg_advisory_unlock(hashtext('report_generator'));
|
|
24
|
+
|
|
25
|
+
-- Transaction-level lock (auto-released on COMMIT/ROLLBACK)
|
|
26
|
+
BEGIN;
|
|
27
|
+
SELECT pg_advisory_xact_lock(hashtext('daily_report'));
|
|
28
|
+
-- ... do work ...
|
|
29
|
+
COMMIT; -- Lock automatically released
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Non-blocking try-lock (returns immediately):
|
|
33
|
+
|
|
34
|
+
```sql
|
|
35
|
+
-- Returns TRUE if acquired, FALSE if already held
|
|
36
|
+
SELECT pg_try_advisory_lock(hashtext('resource_name'));
|
|
37
|
+
-- Application checks result, skips or retries if not acquired
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Deadlock Prevention
|
|
41
|
+
|
|
42
|
+
Deadlocks occur when transactions lock resources in different orders. Always acquire locks in a **consistent order**.
|
|
43
|
+
|
|
44
|
+
**Incorrect (inconsistent lock ordering → deadlock):**
|
|
45
|
+
|
|
46
|
+
```sql
|
|
47
|
+
-- Transaction A -- Transaction B
|
|
48
|
+
BEGIN; BEGIN;
|
|
49
|
+
UPDATE accounts SET balance = UPDATE accounts SET balance =
|
|
50
|
+
balance - 100 WHERE id = 1; balance - 50 WHERE id = 2;
|
|
51
|
+
-- A locks row 1 -- B locks row 2
|
|
52
|
+
|
|
53
|
+
UPDATE accounts SET balance = UPDATE accounts SET balance =
|
|
54
|
+
balance + 100 WHERE id = 2; balance + 50 WHERE id = 1;
|
|
55
|
+
-- A waits for B's lock on row 2 -- B waits for A's lock on row 1
|
|
56
|
+
-- DEADLOCK!
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Correct (acquire all locks in ID order first):**
|
|
60
|
+
|
|
61
|
+
```sql
|
|
62
|
+
BEGIN;
|
|
63
|
+
-- Lock rows in consistent order BEFORE updating
|
|
64
|
+
SELECT * FROM accounts WHERE id IN (1, 2) ORDER BY id FOR UPDATE;
|
|
65
|
+
|
|
66
|
+
-- Now update in any order — locks already held
|
|
67
|
+
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
|
|
68
|
+
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
|
|
69
|
+
COMMIT;
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Alternative — single statement (acquires all locks atomically):
|
|
73
|
+
|
|
74
|
+
```sql
|
|
75
|
+
UPDATE accounts
|
|
76
|
+
SET balance = balance + CASE id
|
|
77
|
+
WHEN 1 THEN -100
|
|
78
|
+
WHEN 2 THEN 100
|
|
79
|
+
END
|
|
80
|
+
WHERE id IN (1, 2);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Detect deadlocks:
|
|
84
|
+
|
|
85
|
+
```sql
|
|
86
|
+
-- Check for recent deadlocks
|
|
87
|
+
SELECT datname, deadlocks FROM pg_stat_database WHERE deadlocks > 0;
|
|
88
|
+
|
|
89
|
+
-- Enable deadlock logging
|
|
90
|
+
SET log_lock_waits = on;
|
|
91
|
+
SET deadlock_timeout = '1s';
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Short Transactions
|
|
95
|
+
|
|
96
|
+
Long-running transactions hold locks that block other queries. Keep transactions as short as possible — **never do external I/O inside a transaction**.
|
|
97
|
+
|
|
98
|
+
**Incorrect (external call inside transaction):**
|
|
99
|
+
|
|
100
|
+
```sql
|
|
101
|
+
BEGIN;
|
|
102
|
+
SELECT * FROM orders WHERE id = 1 FOR UPDATE; -- Lock acquired
|
|
103
|
+
-- Application makes HTTP call to payment API (2-5 seconds)
|
|
104
|
+
-- ALL other queries touching this row are blocked!
|
|
105
|
+
UPDATE orders SET status = 'paid' WHERE id = 1;
|
|
106
|
+
COMMIT; -- Lock held for entire duration
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Correct (minimal transaction scope):**
|
|
110
|
+
|
|
111
|
+
```sql
|
|
112
|
+
-- Do validation and API calls OUTSIDE the transaction
|
|
113
|
+
-- Application: response = await paymentAPI.charge(...)
|
|
114
|
+
|
|
115
|
+
-- Only hold the lock for the actual database update
|
|
116
|
+
BEGIN;
|
|
117
|
+
UPDATE orders
|
|
118
|
+
SET status = 'paid', payment_id = $1
|
|
119
|
+
WHERE id = $2 AND status = 'pending'
|
|
120
|
+
RETURNING *;
|
|
121
|
+
COMMIT; -- Lock held for milliseconds
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Prevent runaway transactions:
|
|
125
|
+
|
|
126
|
+
```sql
|
|
127
|
+
-- Abort queries running longer than 30 seconds
|
|
128
|
+
SET statement_timeout = '30s';
|
|
129
|
+
|
|
130
|
+
-- Per-transaction override
|
|
131
|
+
SET LOCAL statement_timeout = '5s';
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## SKIP LOCKED Queue Pattern
|
|
135
|
+
|
|
136
|
+
When multiple workers process a queue, `SKIP LOCKED` lets each worker grab the next available row without waiting for other workers' locks. **10x throughput** for worker queues.
|
|
137
|
+
|
|
138
|
+
**Incorrect (workers block each other):**
|
|
139
|
+
|
|
140
|
+
```sql
|
|
141
|
+
BEGIN;
|
|
142
|
+
SELECT * FROM jobs WHERE status = 'pending'
|
|
143
|
+
ORDER BY created_at LIMIT 1 FOR UPDATE;
|
|
144
|
+
-- Worker 2 waits for Worker 1's lock to release!
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Correct (SKIP LOCKED — parallel processing):**
|
|
148
|
+
|
|
149
|
+
```sql
|
|
150
|
+
BEGIN;
|
|
151
|
+
SELECT * FROM jobs
|
|
152
|
+
WHERE status = 'pending'
|
|
153
|
+
ORDER BY created_at
|
|
154
|
+
LIMIT 1
|
|
155
|
+
FOR UPDATE SKIP LOCKED;
|
|
156
|
+
-- Worker 1 gets job 1, Worker 2 gets job 2 (no waiting)
|
|
157
|
+
|
|
158
|
+
UPDATE jobs SET status = 'processing' WHERE id = $1;
|
|
159
|
+
COMMIT;
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Atomic claim-and-update (single statement):
|
|
163
|
+
|
|
164
|
+
```sql
|
|
165
|
+
UPDATE jobs
|
|
166
|
+
SET status = 'processing', worker_id = $1, started_at = now()
|
|
167
|
+
WHERE id = (
|
|
168
|
+
SELECT id FROM jobs
|
|
169
|
+
WHERE status = 'pending'
|
|
170
|
+
ORDER BY created_at
|
|
171
|
+
LIMIT 1
|
|
172
|
+
FOR UPDATE SKIP LOCKED
|
|
173
|
+
)
|
|
174
|
+
RETURNING *;
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## References
|
|
178
|
+
|
|
179
|
+
- [Advisory Locks](https://www.postgresql.org/docs/current/explicit-locking.html#ADVISORY-LOCKS)
|
|
180
|
+
- [Deadlocks](https://www.postgresql.org/docs/current/explicit-locking.html#LOCKING-DEADLOCKS)
|
|
181
|
+
- [Transaction Management](https://www.postgresql.org/docs/current/tutorial-transactions.html)
|
|
182
|
+
- [SELECT FOR UPDATE SKIP LOCKED](https://www.postgresql.org/docs/current/sql-select.html#SQL-FOR-UPDATE-SHARE)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# PostgreSQL Connection Management
|
|
2
|
+
|
|
3
|
+
Connection pooling and limit configuration to prevent database crashes and handle high concurrency.
|
|
4
|
+
|
|
5
|
+
## Connection Pooling
|
|
6
|
+
|
|
7
|
+
PostgreSQL forks a new process per connection, each consuming 1-3MB RAM. Without pooling, applications exhaust connections under load.
|
|
8
|
+
|
|
9
|
+
**Without pooling (connection per request):**
|
|
10
|
+
|
|
11
|
+
```sql
|
|
12
|
+
-- 500 concurrent users = 500 connections = database crash
|
|
13
|
+
SELECT count(*) FROM pg_stat_activity; -- 487 connections!
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**With pooling (shared pool):**
|
|
17
|
+
|
|
18
|
+
```sql
|
|
19
|
+
-- 500 concurrent users share 10 actual database connections
|
|
20
|
+
-- Connection pooler sits between application and database
|
|
21
|
+
SELECT count(*) FROM pg_stat_activity; -- 10 connections
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Pool Sizing Formula
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
pool_size = (CPU cores × 2) + spindle_count
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Example for 4 cores with SSD: `(4 × 2) + 1 = 9` connections. Round up to 10.
|
|
31
|
+
|
|
32
|
+
### Pool Modes
|
|
33
|
+
|
|
34
|
+
| Mode | Behavior | Use When |
|
|
35
|
+
| --------------- | ------------------------------------------ | ---------------------------------------------- |
|
|
36
|
+
| **Transaction** | Connection returned after each transaction | Most web apps (stateless requests) |
|
|
37
|
+
| **Session** | Connection held for entire client session | Prepared statements, temp tables, SET commands |
|
|
38
|
+
|
|
39
|
+
**Transaction mode** is best for most applications — it maximizes connection reuse.
|
|
40
|
+
|
|
41
|
+
**Session mode** is required when using:
|
|
42
|
+
|
|
43
|
+
- Prepared statements (`PREPARE`/`EXECUTE`)
|
|
44
|
+
- Temporary tables (`CREATE TEMP TABLE`)
|
|
45
|
+
- Session-level settings (`SET` commands)
|
|
46
|
+
- `LISTEN`/`NOTIFY`
|
|
47
|
+
|
|
48
|
+
## Connection Limits
|
|
49
|
+
|
|
50
|
+
Too many connections exhaust memory and degrade performance. Set limits based on available resources.
|
|
51
|
+
|
|
52
|
+
**Incorrect (excessive connections):**
|
|
53
|
+
|
|
54
|
+
```sql
|
|
55
|
+
SHOW max_connections; -- 500 (way too high for 4GB RAM)
|
|
56
|
+
-- Each connection uses 1-3MB RAM
|
|
57
|
+
-- 500 × 2MB = 1GB just for connections!
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Correct (calculate based on resources):**
|
|
61
|
+
|
|
62
|
+
```sql
|
|
63
|
+
-- Formula: (RAM_MB / 5MB per connection) - reserved
|
|
64
|
+
-- For 4GB: (4096 / 5) - 10 = ~800 theoretical max
|
|
65
|
+
-- Practical recommendation: 100-200 for query performance
|
|
66
|
+
|
|
67
|
+
ALTER SYSTEM SET max_connections = 100;
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### work_mem Budget
|
|
71
|
+
|
|
72
|
+
```sql
|
|
73
|
+
-- work_mem × max_connections should not exceed 25% of RAM
|
|
74
|
+
-- For 4GB RAM with 100 connections: 1024MB / 100 = 10MB max
|
|
75
|
+
ALTER SYSTEM SET work_mem = '8MB'; -- 8MB × 100 = 800MB (safe)
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Monitor Connection Usage
|
|
79
|
+
|
|
80
|
+
```sql
|
|
81
|
+
-- Connections by state
|
|
82
|
+
SELECT count(*), state
|
|
83
|
+
FROM pg_stat_activity
|
|
84
|
+
GROUP BY state;
|
|
85
|
+
|
|
86
|
+
-- Find long-running idle connections
|
|
87
|
+
SELECT pid, now() - state_change AS idle_time, query
|
|
88
|
+
FROM pg_stat_activity
|
|
89
|
+
WHERE state = 'idle'
|
|
90
|
+
ORDER BY idle_time DESC;
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## References
|
|
94
|
+
|
|
95
|
+
- [Connection Settings](https://www.postgresql.org/docs/current/runtime-config-connection.html)
|
|
96
|
+
- [pg_stat_activity](https://www.postgresql.org/docs/current/monitoring-stats.html#MONITORING-PG-STAT-ACTIVITY-VIEW)
|
|
97
|
+
- [Resource Consumption](https://www.postgresql.org/docs/current/runtime-config-resource.html)
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# PostgreSQL Data Access Patterns
|
|
2
|
+
|
|
3
|
+
Efficient patterns for bulk operations, pagination, upserts, and table partitioning.
|
|
4
|
+
|
|
5
|
+
## Batch Inserts
|
|
6
|
+
|
|
7
|
+
Individual INSERT statements have high overhead per row. Batch multiple rows or use COPY for bulk loading.
|
|
8
|
+
|
|
9
|
+
**Incorrect (individual inserts — 1000 round trips):**
|
|
10
|
+
|
|
11
|
+
```sql
|
|
12
|
+
INSERT INTO events (user_id, action) VALUES (1, 'click');
|
|
13
|
+
INSERT INTO events (user_id, action) VALUES (1, 'view');
|
|
14
|
+
INSERT INTO events (user_id, action) VALUES (2, 'click');
|
|
15
|
+
-- ... 1000 separate statements = 1000 round trips
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
**Correct (multi-row insert — 1 round trip):**
|
|
19
|
+
|
|
20
|
+
```sql
|
|
21
|
+
INSERT INTO events (user_id, action) VALUES
|
|
22
|
+
(1, 'click'),
|
|
23
|
+
(1, 'view'),
|
|
24
|
+
(2, 'click'),
|
|
25
|
+
-- ... up to ~1000 rows per batch
|
|
26
|
+
(999, 'view');
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
**Fastest (COPY for bulk loading):**
|
|
30
|
+
|
|
31
|
+
```sql
|
|
32
|
+
COPY events (user_id, action, created_at)
|
|
33
|
+
FROM '/path/to/data.csv'
|
|
34
|
+
WITH (FORMAT csv, HEADER true);
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Impact: **10-50x faster** than individual inserts.
|
|
38
|
+
|
|
39
|
+
## Cursor Pagination (vs OFFSET)
|
|
40
|
+
|
|
41
|
+
OFFSET-based pagination scans all skipped rows, getting slower on deeper pages. Cursor/keyset pagination is O(1) regardless of page depth.
|
|
42
|
+
|
|
43
|
+
**Incorrect (OFFSET — gets slower per page):**
|
|
44
|
+
|
|
45
|
+
```sql
|
|
46
|
+
-- Page 1: scans 20 rows
|
|
47
|
+
SELECT * FROM products ORDER BY id LIMIT 20 OFFSET 0;
|
|
48
|
+
|
|
49
|
+
-- Page 100: scans 2000 rows to skip 1980
|
|
50
|
+
SELECT * FROM products ORDER BY id LIMIT 20 OFFSET 1980;
|
|
51
|
+
|
|
52
|
+
-- Page 10000: scans 200,000 rows!
|
|
53
|
+
SELECT * FROM products ORDER BY id LIMIT 20 OFFSET 199980;
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
**Correct (keyset — constant speed):**
|
|
57
|
+
|
|
58
|
+
```sql
|
|
59
|
+
-- Page 1: get first 20
|
|
60
|
+
SELECT * FROM products ORDER BY id LIMIT 20;
|
|
61
|
+
-- Application stores last_id = 20
|
|
62
|
+
|
|
63
|
+
-- Page 2: start after last ID (uses index, always fast)
|
|
64
|
+
SELECT * FROM products WHERE id > 20 ORDER BY id LIMIT 20;
|
|
65
|
+
|
|
66
|
+
-- Page 10000: same speed as page 1
|
|
67
|
+
SELECT * FROM products WHERE id > 199980 ORDER BY id LIMIT 20;
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Multi-column sorting:
|
|
71
|
+
|
|
72
|
+
```sql
|
|
73
|
+
-- Cursor includes ALL sort columns
|
|
74
|
+
SELECT * FROM products
|
|
75
|
+
WHERE (created_at, id) > ('2024-01-15 10:00:00', 12345)
|
|
76
|
+
ORDER BY created_at, id
|
|
77
|
+
LIMIT 20;
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Upsert (INSERT ... ON CONFLICT)
|
|
81
|
+
|
|
82
|
+
Separate SELECT-then-INSERT creates race conditions. Use atomic upsert instead.
|
|
83
|
+
|
|
84
|
+
**Incorrect (race condition):**
|
|
85
|
+
|
|
86
|
+
```sql
|
|
87
|
+
-- Two requests check simultaneously, both find nothing, both try to insert
|
|
88
|
+
SELECT * FROM settings WHERE user_id = 123 AND key = 'theme';
|
|
89
|
+
INSERT INTO settings (user_id, key, value) VALUES (123, 'theme', 'dark');
|
|
90
|
+
-- One succeeds, one fails with duplicate key error!
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**Correct (atomic upsert):**
|
|
94
|
+
|
|
95
|
+
```sql
|
|
96
|
+
-- Insert or update in a single atomic operation
|
|
97
|
+
INSERT INTO settings (user_id, key, value)
|
|
98
|
+
VALUES (123, 'theme', 'dark')
|
|
99
|
+
ON CONFLICT (user_id, key)
|
|
100
|
+
DO UPDATE SET value = EXCLUDED.value, updated_at = now()
|
|
101
|
+
RETURNING *;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Insert-or-ignore pattern:
|
|
105
|
+
|
|
106
|
+
```sql
|
|
107
|
+
INSERT INTO page_views (page_id, user_id)
|
|
108
|
+
VALUES (1, 123)
|
|
109
|
+
ON CONFLICT (page_id, user_id) DO NOTHING;
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
## Table Partitioning
|
|
113
|
+
|
|
114
|
+
Partitioning splits a large table into smaller physical pieces. Queries only scan relevant partitions. Maintenance (VACUUM, DROP old data) operates on individual partitions.
|
|
115
|
+
|
|
116
|
+
**When to partition:**
|
|
117
|
+
|
|
118
|
+
- Tables > 100M rows
|
|
119
|
+
- Time-series data with date-range queries
|
|
120
|
+
- Need to efficiently drop old data (DROP TABLE is instant vs DELETE taking hours)
|
|
121
|
+
|
|
122
|
+
**Without partitioning (single large table):**
|
|
123
|
+
|
|
124
|
+
```sql
|
|
125
|
+
-- 500M rows, queries scan everything
|
|
126
|
+
SELECT * FROM events WHERE created_at > '2024-01-01'; -- Slow
|
|
127
|
+
VACUUM events; -- Takes hours
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
**With partitioning (by time range):**
|
|
131
|
+
|
|
132
|
+
```sql
|
|
133
|
+
CREATE TABLE events (
|
|
134
|
+
id bigint GENERATED ALWAYS AS IDENTITY,
|
|
135
|
+
created_at timestamptz NOT NULL,
|
|
136
|
+
data jsonb
|
|
137
|
+
) PARTITION BY RANGE (created_at);
|
|
138
|
+
|
|
139
|
+
-- Monthly partitions
|
|
140
|
+
CREATE TABLE events_2024_01 PARTITION OF events
|
|
141
|
+
FOR VALUES FROM ('2024-01-01') TO ('2024-02-01');
|
|
142
|
+
CREATE TABLE events_2024_02 PARTITION OF events
|
|
143
|
+
FOR VALUES FROM ('2024-02-01') TO ('2024-03-01');
|
|
144
|
+
|
|
145
|
+
-- Queries only scan relevant partitions
|
|
146
|
+
SELECT * FROM events WHERE created_at > '2024-01-15';
|
|
147
|
+
-- Only scans events_2024_01 and later
|
|
148
|
+
|
|
149
|
+
-- Drop old data instantly (no row-by-row DELETE)
|
|
150
|
+
DROP TABLE events_2023_01;
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Impact: **5-20x faster** queries and maintenance on large tables.
|
|
154
|
+
|
|
155
|
+
## References
|
|
156
|
+
|
|
157
|
+
- [INSERT ON CONFLICT](https://www.postgresql.org/docs/current/sql-insert.html#SQL-ON-CONFLICT)
|
|
158
|
+
- [COPY](https://www.postgresql.org/docs/current/sql-copy.html)
|
|
159
|
+
- [Table Partitioning](https://www.postgresql.org/docs/current/ddl-partitioning.html)
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
# PostgreSQL Monitoring & Diagnostics
|
|
2
|
+
|
|
3
|
+
Deep query analysis, performance tracking, and maintenance tuning beyond the basics in SKILL.md.
|
|
4
|
+
|
|
5
|
+
## EXPLAIN ANALYZE Deep Dive
|
|
6
|
+
|
|
7
|
+
`EXPLAIN ANALYZE` executes the query and shows actual timings — the definitive tool for diagnosing slow queries.
|
|
8
|
+
|
|
9
|
+
```sql
|
|
10
|
+
EXPLAIN (ANALYZE, BUFFERS, FORMAT TEXT)
|
|
11
|
+
SELECT * FROM orders WHERE customer_id = 123 AND status = 'pending';
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
### Red Flag Checklist
|
|
15
|
+
|
|
16
|
+
Read the output and look for these problems:
|
|
17
|
+
|
|
18
|
+
| Red Flag | What It Means | Fix |
|
|
19
|
+
| ----------------------------- | --------------------------------- | ---------------------------------------------------------- |
|
|
20
|
+
| `Seq Scan` on large table | Missing index | Add index on filtered columns |
|
|
21
|
+
| High `Rows Removed by Filter` | Poor selectivity or missing index | Add more specific index or composite index |
|
|
22
|
+
| `Buffers: read >> hit` | Data not cached in memory | Increase `shared_buffers` or add index to reduce scan |
|
|
23
|
+
| `Sort Method: external merge` | `work_mem` too low for sort | Increase `work_mem` or add index matching ORDER BY |
|
|
24
|
+
| `Nested Loop` with high loops | Potentially slow join | Check for missing index on join column, consider Hash Join |
|
|
25
|
+
| `Hash Batches > 1` | Hash table spilled to disk | Increase `work_mem` |
|
|
26
|
+
|
|
27
|
+
### Example Output Analysis
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Seq Scan on orders (cost=0.00..25000.00 rows=50 width=100)
|
|
31
|
+
(actual time=0.015..450.123 rows=50 loops=1)
|
|
32
|
+
Filter: ((customer_id = 123) AND (status = 'pending'::text))
|
|
33
|
+
Rows Removed by Filter: 999950 ← Scanned 1M rows, kept 50
|
|
34
|
+
Buffers: shared hit=5000 read=15000 ← 15K blocks from disk (slow)
|
|
35
|
+
Planning Time: 0.150 ms
|
|
36
|
+
Execution Time: 450.500 ms ← Fix: add composite index
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
After adding index:
|
|
40
|
+
|
|
41
|
+
```sql
|
|
42
|
+
CREATE INDEX orders_customer_status_idx ON orders (customer_id, status);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
Index Scan using orders_customer_status_idx on orders
|
|
47
|
+
(cost=0.42..8.44 rows=50 width=100)
|
|
48
|
+
(actual time=0.025..0.089 rows=50 loops=1)
|
|
49
|
+
Buffers: shared hit=4
|
|
50
|
+
Execution Time: 0.112 ms ← 4000x faster
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## pg_stat_statements
|
|
54
|
+
|
|
55
|
+
Tracks execution statistics for all queries. Essential for finding the queries consuming the most resources.
|
|
56
|
+
|
|
57
|
+
```sql
|
|
58
|
+
-- Enable the extension (once)
|
|
59
|
+
CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
|
|
60
|
+
|
|
61
|
+
-- Top 10 slowest queries by total execution time
|
|
62
|
+
SELECT
|
|
63
|
+
calls,
|
|
64
|
+
round(total_exec_time::numeric, 2) AS total_time_ms,
|
|
65
|
+
round(mean_exec_time::numeric, 2) AS mean_time_ms,
|
|
66
|
+
query
|
|
67
|
+
FROM pg_stat_statements
|
|
68
|
+
ORDER BY total_exec_time DESC
|
|
69
|
+
LIMIT 10;
|
|
70
|
+
|
|
71
|
+
-- Most frequent queries (may indicate N+1 patterns)
|
|
72
|
+
SELECT calls, query
|
|
73
|
+
FROM pg_stat_statements
|
|
74
|
+
ORDER BY calls DESC
|
|
75
|
+
LIMIT 10;
|
|
76
|
+
|
|
77
|
+
-- Queries with high average time (optimization candidates)
|
|
78
|
+
SELECT query, round(mean_exec_time::numeric, 2) AS mean_ms, calls
|
|
79
|
+
FROM pg_stat_statements
|
|
80
|
+
WHERE mean_exec_time > 100 -- Over 100ms average
|
|
81
|
+
ORDER BY mean_exec_time DESC;
|
|
82
|
+
|
|
83
|
+
-- Reset statistics after optimization round
|
|
84
|
+
SELECT pg_stat_statements_reset();
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## VACUUM & ANALYZE
|
|
88
|
+
|
|
89
|
+
Outdated statistics cause the query planner to make poor decisions. `VACUUM` reclaims dead tuple space. `ANALYZE` updates statistics used by the planner.
|
|
90
|
+
|
|
91
|
+
### When to Run
|
|
92
|
+
|
|
93
|
+
```sql
|
|
94
|
+
-- Manually analyze after large data changes (bulk import, migration)
|
|
95
|
+
ANALYZE orders;
|
|
96
|
+
|
|
97
|
+
-- Analyze specific columns used in WHERE clauses
|
|
98
|
+
ANALYZE orders (status, created_at);
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Check Staleness
|
|
102
|
+
|
|
103
|
+
```sql
|
|
104
|
+
-- Tables sorted by most stale (never analyzed first)
|
|
105
|
+
SELECT
|
|
106
|
+
relname,
|
|
107
|
+
last_vacuum,
|
|
108
|
+
last_autovacuum,
|
|
109
|
+
last_analyze,
|
|
110
|
+
last_autoanalyze,
|
|
111
|
+
n_dead_tup
|
|
112
|
+
FROM pg_stat_user_tables
|
|
113
|
+
ORDER BY last_analyze NULLS FIRST;
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### Autovacuum Tuning for High-Churn Tables
|
|
117
|
+
|
|
118
|
+
Default autovacuum triggers at 20% dead tuples — too late for busy tables.
|
|
119
|
+
|
|
120
|
+
```sql
|
|
121
|
+
-- Tune for high-write tables (e.g., events, logs, queue)
|
|
122
|
+
ALTER TABLE events SET (
|
|
123
|
+
autovacuum_vacuum_scale_factor = 0.05, -- Vacuum at 5% dead tuples (default 20%)
|
|
124
|
+
autovacuum_analyze_scale_factor = 0.02 -- Analyze at 2% changes (default 10%)
|
|
125
|
+
);
|
|
126
|
+
|
|
127
|
+
-- Check autovacuum progress
|
|
128
|
+
SELECT * FROM pg_stat_progress_vacuum;
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## References
|
|
132
|
+
|
|
133
|
+
- [EXPLAIN](https://www.postgresql.org/docs/current/sql-explain.html)
|
|
134
|
+
- [pg_stat_statements](https://www.postgresql.org/docs/current/pgstatstatements.html)
|
|
135
|
+
- [Routine Vacuuming](https://www.postgresql.org/docs/current/routine-vacuuming.html)
|
|
136
|
+
- [Monitoring Statistics](https://www.postgresql.org/docs/current/monitoring-stats.html)
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# PostgreSQL Row-Level Security (RLS)
|
|
2
|
+
|
|
3
|
+
Database-enforced access control that ensures users only see their own data, regardless of application bugs or SQL injection.
|
|
4
|
+
|
|
5
|
+
## RLS Basics
|
|
6
|
+
|
|
7
|
+
Row Level Security enforces data access at the database level. Even if application code is bypassed, the database itself prevents unauthorized access.
|
|
8
|
+
|
|
9
|
+
**Without RLS (application-level filtering only):**
|
|
10
|
+
|
|
11
|
+
```sql
|
|
12
|
+
-- Relies on application to filter — bug or bypass exposes ALL data
|
|
13
|
+
SELECT * FROM orders WHERE user_id = $current_user_id;
|
|
14
|
+
|
|
15
|
+
-- If application logic is bypassed:
|
|
16
|
+
SELECT * FROM orders; -- Returns ALL orders for ALL users
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**With RLS (database-enforced):**
|
|
20
|
+
|
|
21
|
+
```sql
|
|
22
|
+
-- Enable RLS on the table
|
|
23
|
+
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
|
|
24
|
+
|
|
25
|
+
-- Create policy: users see only their own orders
|
|
26
|
+
CREATE POLICY orders_user_policy ON orders
|
|
27
|
+
FOR ALL
|
|
28
|
+
USING (user_id = current_setting('app.current_user_id')::bigint);
|
|
29
|
+
|
|
30
|
+
-- Force RLS even for table owners (critical for security)
|
|
31
|
+
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
|
|
32
|
+
|
|
33
|
+
-- Set user context before queries
|
|
34
|
+
SET app.current_user_id = '123';
|
|
35
|
+
SELECT * FROM orders; -- Only returns orders for user 123
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Policy scoped to a specific role:
|
|
39
|
+
|
|
40
|
+
```sql
|
|
41
|
+
CREATE POLICY orders_user_policy ON orders
|
|
42
|
+
FOR ALL
|
|
43
|
+
TO authenticated
|
|
44
|
+
USING (user_id = current_setting('app.current_user_id')::uuid);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## RLS Performance Optimization
|
|
48
|
+
|
|
49
|
+
Poorly written RLS policies can cause severe performance issues. The key pattern: **wrap function calls in a subquery** so they execute once, not per-row.
|
|
50
|
+
|
|
51
|
+
**Incorrect (function called for every row):**
|
|
52
|
+
|
|
53
|
+
```sql
|
|
54
|
+
CREATE POLICY orders_policy ON orders
|
|
55
|
+
USING (get_current_user_id() = user_id);
|
|
56
|
+
-- get_current_user_id() called PER ROW
|
|
57
|
+
-- With 1M rows = 1M function calls
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
**Correct (function called once, result cached):**
|
|
61
|
+
|
|
62
|
+
```sql
|
|
63
|
+
CREATE POLICY orders_policy ON orders
|
|
64
|
+
USING ((SELECT get_current_user_id()) = user_id);
|
|
65
|
+
-- Wrapped in SELECT = called ONCE, result reused
|
|
66
|
+
-- 100x+ faster on large tables
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
For complex multi-table checks, use a `SECURITY DEFINER` helper:
|
|
70
|
+
|
|
71
|
+
```sql
|
|
72
|
+
-- Helper function runs as definer (bypasses RLS for lookups)
|
|
73
|
+
CREATE OR REPLACE FUNCTION is_team_member(p_team_id bigint)
|
|
74
|
+
RETURNS boolean
|
|
75
|
+
LANGUAGE sql
|
|
76
|
+
SECURITY DEFINER
|
|
77
|
+
SET search_path = '' -- Prevent search_path attacks
|
|
78
|
+
AS $$
|
|
79
|
+
SELECT EXISTS (
|
|
80
|
+
SELECT 1 FROM public.team_members
|
|
81
|
+
WHERE team_id = p_team_id
|
|
82
|
+
AND user_id = (SELECT current_setting('app.current_user_id')::bigint)
|
|
83
|
+
);
|
|
84
|
+
$$;
|
|
85
|
+
|
|
86
|
+
-- Use in policy (indexed lookup, not per-row scan)
|
|
87
|
+
CREATE POLICY team_orders_policy ON orders
|
|
88
|
+
USING ((SELECT is_team_member(team_id)));
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Always index columns used in RLS policies:**
|
|
92
|
+
|
|
93
|
+
```sql
|
|
94
|
+
CREATE INDEX orders_user_id_idx ON orders (user_id);
|
|
95
|
+
CREATE INDEX team_members_lookup_idx ON team_members (team_id, user_id);
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
## Privilege Management
|
|
99
|
+
|
|
100
|
+
Grant only the minimum permissions required. Never use superuser for application queries.
|
|
101
|
+
|
|
102
|
+
**Incorrect (overly broad permissions):**
|
|
103
|
+
|
|
104
|
+
```sql
|
|
105
|
+
-- Any SQL injection becomes catastrophic
|
|
106
|
+
GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO app_user;
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
**Correct (minimal, specific grants):**
|
|
110
|
+
|
|
111
|
+
```sql
|
|
112
|
+
-- Create roles with no default privileges
|
|
113
|
+
CREATE ROLE app_readonly NOLOGIN;
|
|
114
|
+
GRANT USAGE ON SCHEMA public TO app_readonly;
|
|
115
|
+
GRANT SELECT ON public.products, public.categories TO app_readonly;
|
|
116
|
+
|
|
117
|
+
-- Write role with limited scope
|
|
118
|
+
CREATE ROLE app_writer NOLOGIN;
|
|
119
|
+
GRANT USAGE ON SCHEMA public TO app_writer;
|
|
120
|
+
GRANT SELECT, INSERT, UPDATE ON public.orders TO app_writer;
|
|
121
|
+
GRANT USAGE ON SEQUENCE orders_id_seq TO app_writer;
|
|
122
|
+
-- No DELETE permission
|
|
123
|
+
|
|
124
|
+
-- Login role inherits from role groups
|
|
125
|
+
CREATE ROLE app_user LOGIN PASSWORD 'secure_password_here';
|
|
126
|
+
GRANT app_writer TO app_user;
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Revoke public defaults (often forgotten):
|
|
130
|
+
|
|
131
|
+
```sql
|
|
132
|
+
REVOKE ALL ON SCHEMA public FROM public;
|
|
133
|
+
REVOKE ALL ON ALL TABLES IN SCHEMA public FROM public;
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## References
|
|
137
|
+
|
|
138
|
+
- [Row Level Security](https://www.postgresql.org/docs/current/ddl-rowsecurity.html)
|
|
139
|
+
- [Roles and Privileges](https://www.postgresql.org/docs/current/user-manag.html)
|
|
140
|
+
- [Security Definer Functions](https://www.postgresql.org/docs/current/sql-createfunction.html#SQL-CREATEFUNCTION-SECURITY)
|