@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,448 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: lgpd-compliance-audit
|
|
3
|
+
description: LGPD (Lei Geral de Proteção de Dados — Brazilian GDPR equivalent) compliance audit. PII identification, consent tracking, right-to-erasure verification, audit log requirements, and incident reporting templates. Use before exposing any user-data-handling project to production.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
metadata:
|
|
6
|
+
author: merlin-framework
|
|
7
|
+
version: "3.0.0"
|
|
8
|
+
auto_activate:
|
|
9
|
+
[lgpd, anpd, right-to-erasure, data-subject-request, cookie-consent, pii]
|
|
10
|
+
tool_reminders:
|
|
11
|
+
[
|
|
12
|
+
LGPD applies to ANY system processing PII of Brazilian residents — even if your company is foreign-based,
|
|
13
|
+
This skill is operational guidance not legal advice — for regulated sectors (financial,
|
|
14
|
+
health) consult an LGPD lawyer before going to production,
|
|
15
|
+
Cookie consent must be revocable AND the revocation must propagate to backend (not just localStorage),
|
|
16
|
+
Right-to-erasure (Art. 18 V) requires actually deleting data — not soft-deleting. Soft-delete only works if user explicitly consents to retention for legal/contractual purposes,
|
|
17
|
+
ANPD breach notification window is 'reasonable time' (interpreted by precedent ~72h) — start the incident clock the moment you discover the leak,
|
|
18
|
+
]
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
# LGPD Compliance Audit Skill
|
|
22
|
+
|
|
23
|
+
**Mission:** Before any Merlin project that processes personal data of
|
|
24
|
+
Brazilian residents goes to production (or after a regulator inquiry), run
|
|
25
|
+
this audit checklist to identify gaps in LGPD compliance, document the
|
|
26
|
+
remediations needed, and produce evidence of due diligence.
|
|
27
|
+
|
|
28
|
+
**Important disclaimer:** This skill is operational guidance based on public
|
|
29
|
+
research, the LGPD text (Lei nº 13.709/2018), and ANPD guidance. It is NOT
|
|
30
|
+
legal advice. For regulated sectors (financial, health, children's data) or
|
|
31
|
+
high-stakes deployments, consult a Brazilian LGPD lawyer before relying on
|
|
32
|
+
this audit.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## When this skill activates
|
|
37
|
+
|
|
38
|
+
- A project that captures user data is approaching production launch
|
|
39
|
+
- After a data breach or suspected PII exposure
|
|
40
|
+
- During quarterly compliance reviews
|
|
41
|
+
- Before signing a contract with a Brazilian client that requires LGPD attestation
|
|
42
|
+
- When a user mentions LGPD, GDPR, "dados pessoais", or "ANPD"
|
|
43
|
+
- During `engineering-audit` of a project handling PII
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## What LGPD requires (the 10 minimum bars)
|
|
48
|
+
|
|
49
|
+
Per the LGPD (Lei nº 13.709/2018) and ANPD guidance, every system processing
|
|
50
|
+
PII of Brazilian residents must:
|
|
51
|
+
|
|
52
|
+
1. **Lawful basis** for each PII processing activity (Art. 7 — 10 hypotheses incl. consent, legitimate interest, contract, legal obligation)
|
|
53
|
+
2. **Transparency** — clear privacy policy explaining what data is collected, why, and with whom shared (Art. 9)
|
|
54
|
+
3. **Purpose limitation** — data used only for the declared purposes (Art. 6 I)
|
|
55
|
+
4. **Data minimization** — collect only what's necessary (Art. 6 III)
|
|
56
|
+
5. **Consent records** — when consent is the lawful basis, persist proof (timestamp, version, IP, user agent) (Art. 8 §1)
|
|
57
|
+
6. **Right of access** — user can request all data held about them (Art. 18 II)
|
|
58
|
+
7. **Right of correction** — user can fix incorrect data (Art. 18 III)
|
|
59
|
+
8. **Right of deletion** — user can request erasure when there's no other lawful basis to retain (Art. 18 VI)
|
|
60
|
+
9. **Right of portability** — user can export their data in interoperable format (Art. 18 V)
|
|
61
|
+
10. **Breach notification** — to ANPD AND affected users, in "reasonable time" (Art. 48)
|
|
62
|
+
|
|
63
|
+
The audit verifies each of these 10 bars in code + UI + documentation.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Audit protocol — 6 phases
|
|
68
|
+
|
|
69
|
+
### Phase 1 — Data inventory (find the PII)
|
|
70
|
+
|
|
71
|
+
For every database table, every API endpoint, and every form, identify:
|
|
72
|
+
|
|
73
|
+
| Field type | LGPD classification | Examples |
|
|
74
|
+
| --------------- | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
|
|
75
|
+
| Common PII | Article 5 I — "personal data" | Name, email, phone, address, IP address, cookies |
|
|
76
|
+
| Sensitive PII | Article 5 II — "sensitive personal data" — extra protections | CPF (national ID), RG, race, religion, health, sexual orientation, biometric, political views, union membership |
|
|
77
|
+
| Children's data | Article 14 — strictest protections | Any PII of users under 18 |
|
|
78
|
+
| Anonymized | Article 5 XI — usually out of scope | Hashed/aggregated data with no re-identification path |
|
|
79
|
+
| Pseudonymized | Article 5 V — reduced but not zero scope | Tokenized or encrypted at rest with key separation |
|
|
80
|
+
|
|
81
|
+
**Audit query templates (Postgres):**
|
|
82
|
+
|
|
83
|
+
```sql
|
|
84
|
+
-- 1. Find all columns that look like PII
|
|
85
|
+
SELECT
|
|
86
|
+
table_schema, table_name, column_name, data_type
|
|
87
|
+
FROM information_schema.columns
|
|
88
|
+
WHERE table_schema = 'public'
|
|
89
|
+
AND (
|
|
90
|
+
column_name ~ '(email|phone|telefone|cpf|cnpj|rg|name|nome|address|endereco|ip|user_agent|birthday|nascimento|gender|race|religion|health|saude)'
|
|
91
|
+
OR column_name LIKE '%_email' OR column_name LIKE '%_phone'
|
|
92
|
+
)
|
|
93
|
+
ORDER BY table_name, column_name;
|
|
94
|
+
|
|
95
|
+
-- 2. Find tables that store PII without timestamp tracking
|
|
96
|
+
-- (Required for retention policy enforcement)
|
|
97
|
+
SELECT table_name FROM information_schema.tables t
|
|
98
|
+
WHERE table_schema = 'public'
|
|
99
|
+
AND NOT EXISTS (
|
|
100
|
+
SELECT 1 FROM information_schema.columns c
|
|
101
|
+
WHERE c.table_schema = t.table_schema
|
|
102
|
+
AND c.table_name = t.table_name
|
|
103
|
+
AND c.column_name IN ('created_at', 'updated_at')
|
|
104
|
+
);
|
|
105
|
+
|
|
106
|
+
-- 3. Find sensitive PII (CPF, etc.) and verify it's encrypted or properly authorized
|
|
107
|
+
SELECT table_name, column_name FROM information_schema.columns
|
|
108
|
+
WHERE table_schema = 'public'
|
|
109
|
+
AND column_name IN ('cpf', 'rg', 'cnh', 'passport', 'health_data');
|
|
110
|
+
-- For each result, verify: is data encrypted at rest? Is access RBAC-controlled?
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Output:** PII inventory document at `.merlin-core/thoughts/shared/research/<date>-pii-inventory.md`
|
|
114
|
+
|
|
115
|
+
### Phase 2 — Lawful basis mapping
|
|
116
|
+
|
|
117
|
+
For each PII column identified, document the lawful basis:
|
|
118
|
+
|
|
119
|
+
| Column | Table | Lawful basis | Justification |
|
|
120
|
+
| ------------------- | ----------------- | ------------------------------- | --------------------------------------------------------- |
|
|
121
|
+
| `email` | `users` | Contract execution (Art. 7 V) | Required to deliver the service the user signed up for |
|
|
122
|
+
| `phone` | `orders` | Contract execution (Art. 7 V) | Needed for delivery coordination |
|
|
123
|
+
| `cpf` | `invoices` | Legal obligation (Art. 7 II) | Required for nota fiscal emission per Brazilian tax law |
|
|
124
|
+
| `analytics_id` | `events` | Legitimate interest (Art. 7 IX) | Service improvement; balanced against minimal user impact |
|
|
125
|
+
| `marketing_consent` | `consent_records` | Consent (Art. 7 I) | Explicit opt-in for marketing emails |
|
|
126
|
+
|
|
127
|
+
**Red flags during this phase:**
|
|
128
|
+
|
|
129
|
+
- ❌ "We collect this just in case" → no lawful basis → DELETE the field
|
|
130
|
+
- ❌ "We collect this for marketing" but no consent record → ADD consent flow OR delete
|
|
131
|
+
- ❌ Sensitive PII (CPF, health) collected via "implicit consent" → REQUIRES explicit consent
|
|
132
|
+
- ❌ Children's data collected without parental consent verification → BLOCK launch
|
|
133
|
+
|
|
134
|
+
### Phase 3 — Consent mechanism verification
|
|
135
|
+
|
|
136
|
+
#### 3.1 Cookie consent banner
|
|
137
|
+
|
|
138
|
+
Required if site uses ANY non-essential cookie (analytics, marketing,
|
|
139
|
+
remarketing, A/B testing).
|
|
140
|
+
|
|
141
|
+
**Audit checklist:**
|
|
142
|
+
|
|
143
|
+
- [ ] Banner appears on first visit (no prior consent)
|
|
144
|
+
- [ ] Banner BLOCKS non-essential cookies until user choice (essential cookies OK)
|
|
145
|
+
- [ ] Banner offers granular control (analytics yes/no, marketing yes/no)
|
|
146
|
+
- [ ] Banner offers "Reject all" with equal prominence to "Accept all"
|
|
147
|
+
- [ ] Choice is persisted (localStorage at minimum)
|
|
148
|
+
- [ ] **Choice is sent to backend** + recorded in `consent_records` table with: user_id (or session_id), consent_type, version, granted/revoked, ip_address, user_agent, granted_at, revoked_at
|
|
149
|
+
- [ ] User can REVOKE consent later (settings page or footer link)
|
|
150
|
+
- [ ] Revocation propagates to backend AND clears related cookies AND stops further processing
|
|
151
|
+
|
|
152
|
+
**Common gap:** A ConsentBanner component exists in the UI but the
|
|
153
|
+
`consent_records` table is EMPTY (0 entries) — frontend doesn't call the
|
|
154
|
+
backend. This is a real LGPD gap.
|
|
155
|
+
|
|
156
|
+
#### 3.2 Form-level consent
|
|
157
|
+
|
|
158
|
+
For any form that collects PII for purposes beyond contract execution
|
|
159
|
+
(marketing, analytics, third-party sharing):
|
|
160
|
+
|
|
161
|
+
- [ ] Checkbox is UNCHECKED by default
|
|
162
|
+
- [ ] Checkbox text is specific (not "I agree to terms" — must specify the actual purpose)
|
|
163
|
+
- [ ] Multiple purposes get multiple checkboxes (don't bundle)
|
|
164
|
+
- [ ] Submission stores the consent record with timestamp + version
|
|
165
|
+
- [ ] User receives confirmation of what they consented to (email or thank-you page)
|
|
166
|
+
|
|
167
|
+
#### 3.3 Consent versioning
|
|
168
|
+
|
|
169
|
+
When privacy policy or terms change materially, existing consent records
|
|
170
|
+
become invalid for the new processing. The system must:
|
|
171
|
+
|
|
172
|
+
- [ ] Tag each consent record with `version` of the policy at consent time
|
|
173
|
+
- [ ] Detect when a user's consent is on an outdated version
|
|
174
|
+
- [ ] Re-prompt the user before proceeding with processing under new terms
|
|
175
|
+
|
|
176
|
+
### Phase 4 — Data subject rights (DSR) endpoints
|
|
177
|
+
|
|
178
|
+
Verify implementation of the 7 user rights:
|
|
179
|
+
|
|
180
|
+
| Right | LGPD article | Endpoint pattern | Example status |
|
|
181
|
+
| -------------------------------- | ------------ | -------------------------------------------- | --------------------------------------------------- |
|
|
182
|
+
| Confirmation of processing | Art. 18 I | `GET /me/data-status` | ❌ Missing |
|
|
183
|
+
| Access (data export) | Art. 18 II | `GET /me/data-export` (ZIP/JSON download) | ❌ Missing |
|
|
184
|
+
| Correction | Art. 18 III | `PATCH /me/profile` | ⚠️ Profile fields editable, not all PII |
|
|
185
|
+
| Anonymization/blocking | Art. 18 IV | `POST /me/data-anonymize` | ❌ Missing |
|
|
186
|
+
| Portability | Art. 18 V | `GET /me/data-export` (interoperable format) | ❌ Missing |
|
|
187
|
+
| Deletion (right to be forgotten) | Art. 18 VI | `DELETE /me/account` | ❌ Missing — only addresses can be deleted |
|
|
188
|
+
| Information about sharing | Art. 18 VII | Privacy policy section | ⚠️ Privacy policy exists; sharing list not explicit |
|
|
189
|
+
|
|
190
|
+
**Audit code pattern:**
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
# Search for endpoints related to user data rights
|
|
194
|
+
grep -rE "(data-export|data-erasure|account.delete|me/profile|right-to-erasure|gdpr|lgpd)" \
|
|
195
|
+
--include="*.ts" --include="*.js" --include="*.py" .
|
|
196
|
+
|
|
197
|
+
# Verify deletion is HARD delete (not soft) for LGPD compliance
|
|
198
|
+
grep -rE "(soft.delete|deleted_at|is_deleted)" --include="*.ts" --include="*.sql" .
|
|
199
|
+
# Soft delete is only LGPD-compliant if user CONSENTS to retention for legal purposes
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
**Critical:** Deletion must be CASCADE — user_id deletion propagates to all
|
|
203
|
+
tables that reference it (orders, audit_logs, consent_records, etc.). Verify
|
|
204
|
+
foreign key constraints have `ON DELETE CASCADE` or explicit cleanup logic.
|
|
205
|
+
|
|
206
|
+
### Phase 5 — Audit logging compliance
|
|
207
|
+
|
|
208
|
+
LGPD doesn't explicitly require audit logs but practical compliance demands
|
|
209
|
+
them. ANPD investigations expect to see:
|
|
210
|
+
|
|
211
|
+
- WHO accessed PII (admin, employee, system process)
|
|
212
|
+
- WHEN they accessed it (ISO 8601 timestamp)
|
|
213
|
+
- WHAT they accessed (entity_type + entity_id)
|
|
214
|
+
- WHY they accessed it (action type or business justification)
|
|
215
|
+
- FROM WHERE (IP address)
|
|
216
|
+
- WITH WHAT (user_agent)
|
|
217
|
+
|
|
218
|
+
**Audit query:**
|
|
219
|
+
|
|
220
|
+
```sql
|
|
221
|
+
-- Coverage rate: % of PII-touching operations that produce an audit_logs entry
|
|
222
|
+
SELECT
|
|
223
|
+
COUNT(*) FILTER (WHERE action LIKE '%_pii%') AS pii_actions_logged,
|
|
224
|
+
-- Compare against estimated PII operations (orders created, users updated, etc.)
|
|
225
|
+
(SELECT COUNT(*) FROM orders) + (SELECT COUNT(*) FROM users) AS estimated_pii_operations,
|
|
226
|
+
ROUND(100.0 * COUNT(*) FILTER (WHERE action LIKE '%_pii%') /
|
|
227
|
+
NULLIF((SELECT COUNT(*) FROM orders) + (SELECT COUNT(*) FROM users), 0), 1) AS coverage_pct
|
|
228
|
+
FROM audit_logs;
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
**Common gap:** 1 audit log entry total (only `payment_webhook_reconciliation`).
|
|
232
|
+
This is an obvious gap — see `audit-logging-middleware` skill (Tier 3 roadmap).
|
|
233
|
+
|
|
234
|
+
### Phase 6 — Breach response readiness
|
|
235
|
+
|
|
236
|
+
LGPD Art. 48 requires breach notification to ANPD AND affected users in
|
|
237
|
+
"reasonable time" (precedent ~72 hours). The system must support:
|
|
238
|
+
|
|
239
|
+
- [ ] Detection capability — log review, alerting on anomalies
|
|
240
|
+
- [ ] Investigation capability — can we determine WHO was affected?
|
|
241
|
+
- [ ] Notification capability — can we email all affected users within 72h?
|
|
242
|
+
- [ ] Documentation — incident response runbook
|
|
243
|
+
- [ ] Contact for ANPD — designated DPO (Data Protection Officer) per Art. 41
|
|
244
|
+
|
|
245
|
+
**Verify:**
|
|
246
|
+
|
|
247
|
+
```bash
|
|
248
|
+
# Is there a documented DPO contact?
|
|
249
|
+
grep -rE "(dpo|encarregado|data.protection.officer)" docs/ README.md
|
|
250
|
+
|
|
251
|
+
# Is there a breach response runbook?
|
|
252
|
+
test -f .merlin-core/thoughts/shared/runbooks/lgpd-breach-response.md
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
---
|
|
256
|
+
|
|
257
|
+
## Concrete artifacts produced by this audit
|
|
258
|
+
|
|
259
|
+
After running the 6 phases, generate these documents in
|
|
260
|
+
`.merlin-core/thoughts/shared/compliance/`:
|
|
261
|
+
|
|
262
|
+
1. **`pii-inventory.md`** — every PII column in every system, with type and lawful basis
|
|
263
|
+
2. **`consent-mechanism-audit.md`** — cookie banner, form consents, versioning status
|
|
264
|
+
3. **`dsr-endpoints-status.md`** — implementation status of each user right
|
|
265
|
+
4. **`audit-log-coverage.md`** — current % coverage + gaps
|
|
266
|
+
5. **`breach-readiness-checklist.md`** — what's in place + what's missing
|
|
267
|
+
6. **`lgpd-gaps-priority-matrix.md`** — ranked remediation plan with timelines
|
|
268
|
+
|
|
269
|
+
---
|
|
270
|
+
|
|
271
|
+
## Example findings (anonymized)
|
|
272
|
+
|
|
273
|
+
This walkthrough is drawn from a real e-commerce audit (anonymized here as
|
|
274
|
+
"AcmeShop"). Initial LGPD posture:
|
|
275
|
+
|
|
276
|
+
| Bar | Status | Evidence |
|
|
277
|
+
| ----------------------- | ----------- | ---------------------------------------------------------------------------------------- |
|
|
278
|
+
| 1. Lawful basis | ⚠️ Implicit | Privacy policy exists but doesn't enumerate basis per data type |
|
|
279
|
+
| 2. Transparency | ✅ | A PrivacyPolicy page exists — Lei 13.709/2018 referenced |
|
|
280
|
+
| 3. Purpose limitation | ⚠️ | No documented purpose register |
|
|
281
|
+
| 4. Data minimization | ✅ | Cart only requires name/phone/email — no CPF (deliberate design decision) |
|
|
282
|
+
| 5. Consent records | ❌ | Table exists (`consent_records`) — has 0 entries (frontend doesn't persist) |
|
|
283
|
+
| 6. Right of access | ❌ | No `/me/data-export` endpoint |
|
|
284
|
+
| 7. Right of correction | ⚠️ | Profile fields editable; not all PII |
|
|
285
|
+
| 8. Right of deletion | ❌ | Only addresses can be deleted via `DELETE /auth/addresses/:id`; no full account deletion |
|
|
286
|
+
| 9. Right of portability | ❌ | No export endpoint |
|
|
287
|
+
| 10. Breach notification | ❌ | No DPO documented; no runbook |
|
|
288
|
+
|
|
289
|
+
**Priority remediation:**
|
|
290
|
+
|
|
291
|
+
1. **Persist cookie consent to DB** (4h work — already have a ConsentBanner component + consent_records table; just need to wire `POST /consent/grant` in backend and call from frontend)
|
|
292
|
+
2. **Implement `DELETE /me/account`** (8h — cascades through orders/cart/audit_logs)
|
|
293
|
+
3. **Implement `GET /me/data-export`** (6h — JSON dump of all user-related rows)
|
|
294
|
+
4. **Designate DPO + add to privacy policy** (1h — write contact email, add to `/privacidade` page)
|
|
295
|
+
5. **Document breach response runbook** (2h — use `incident-response-runbook` skill template, Tier 3 roadmap)
|
|
296
|
+
6. **Tighten DMARC to `p=quarantine`** then `p=reject`
|
|
297
|
+
7. **Audit log middleware** (4h via `audit-logging-middleware` skill, Tier 3)
|
|
298
|
+
|
|
299
|
+
---
|
|
300
|
+
|
|
301
|
+
## Common gotchas
|
|
302
|
+
|
|
303
|
+
### Gotcha #1 — "We anonymize, so LGPD doesn't apply"
|
|
304
|
+
|
|
305
|
+
LGPD Art. 12: anonymization must be IRREVERSIBLE. If you can re-identify
|
|
306
|
+
(via cross-reference with other tables, or with the original key in another
|
|
307
|
+
system), it's pseudonymized — still in scope. True anonymization is rare in
|
|
308
|
+
practice.
|
|
309
|
+
|
|
310
|
+
### Gotcha #2 — Cookie consent in localStorage only
|
|
311
|
+
|
|
312
|
+
ANPD has fined companies for "consent" that only lives client-side. The
|
|
313
|
+
backend must have proof of consent (record with timestamp, IP, version).
|
|
314
|
+
localStorage is for UX (don't show the banner again); the legal record is
|
|
315
|
+
server-side.
|
|
316
|
+
|
|
317
|
+
### Gotcha #3 — "Soft delete" of users
|
|
318
|
+
|
|
319
|
+
Setting `deleted_at = NOW()` is NOT a LGPD-compliant deletion unless the
|
|
320
|
+
user consents to retention for a specific legal/contractual purpose
|
|
321
|
+
(e.g., tax records require 5-year retention). Default to HARD DELETE.
|
|
322
|
+
|
|
323
|
+
### Gotcha #4 — Third-party processors (e.g., MercadoPago, Resend)
|
|
324
|
+
|
|
325
|
+
You're responsible for ensuring your processors are LGPD-compliant. Have a
|
|
326
|
+
DPA (Data Processing Agreement) with each. Most major providers have public
|
|
327
|
+
DPAs — link them from your privacy policy.
|
|
328
|
+
|
|
329
|
+
### Gotcha #5 — International data transfers
|
|
330
|
+
|
|
331
|
+
If you send PII to servers outside Brazil (e.g., AWS us-east-1, OpenAI),
|
|
332
|
+
LGPD Art. 33 requires safeguards (adequacy decision, Standard Contractual
|
|
333
|
+
Clauses, or other mechanism). Document your data flow geography.
|
|
334
|
+
|
|
335
|
+
### Gotcha #6 — Children's data
|
|
336
|
+
|
|
337
|
+
Anyone under 18 needs parental consent (Art. 14). If your service doesn't
|
|
338
|
+
gate by age, you may be processing children's data unknowingly. Verify with
|
|
339
|
+
an age check OR explicit "this service is for 18+" prominently displayed.
|
|
340
|
+
|
|
341
|
+
### Gotcha #7 — Right to erasure has limits
|
|
342
|
+
|
|
343
|
+
LGPD Art. 16 allows retention even after deletion request for: legal
|
|
344
|
+
obligation (tax, financial records), research (anonymized), legitimate
|
|
345
|
+
interest (with documented balancing test), or contract execution. But the
|
|
346
|
+
default must be DELETE; retention requires justification.
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
## Composable templates
|
|
351
|
+
|
|
352
|
+
### Privacy policy section template
|
|
353
|
+
|
|
354
|
+
```markdown
|
|
355
|
+
## Seus direitos (Art. 18 LGPD)
|
|
356
|
+
|
|
357
|
+
Você tem o direito de:
|
|
358
|
+
|
|
359
|
+
1. **Acessar** seus dados — solicite via `me@<domain>` ou painel de conta
|
|
360
|
+
2. **Corrigir** dados incorretos — edite no painel de conta ou solicite via email
|
|
361
|
+
3. **Excluir** seus dados — clique em "Excluir minha conta" no painel ou solicite via email; processamos em até 15 dias úteis
|
|
362
|
+
4. **Portar** seus dados — baixe em formato JSON via "Exportar meus dados" no painel
|
|
363
|
+
5. **Revogar consentimento** — desmarque opções no painel "Privacidade"; processamento cessa imediatamente
|
|
364
|
+
6. **Saber com quem compartilhamos** — veja seção "Compartilhamento" abaixo
|
|
365
|
+
|
|
366
|
+
Contato do Encarregado (DPO): `dpo@<domain>` | Tel: <numero>
|
|
367
|
+
|
|
368
|
+
Reclamações podem ser feitas à ANPD: gov.br/anpd
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### `consent_records` schema template
|
|
372
|
+
|
|
373
|
+
```sql
|
|
374
|
+
CREATE TABLE consent_records (
|
|
375
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
376
|
+
user_id UUID REFERENCES users(id) ON DELETE CASCADE, -- nullable for anonymous consents (cookies)
|
|
377
|
+
session_id VARCHAR(64), -- for pre-auth cookie consent
|
|
378
|
+
consent_type VARCHAR(50) NOT NULL, -- 'cookies_essential' | 'cookies_analytics' | 'cookies_marketing' | 'newsletter' | 'data_processing' | ...
|
|
379
|
+
version VARCHAR(20) NOT NULL, -- privacy policy / terms version at time of consent
|
|
380
|
+
granted BOOLEAN NOT NULL, -- true = granted, false = revoked
|
|
381
|
+
granted_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
382
|
+
revoked_at TIMESTAMPTZ,
|
|
383
|
+
ip_address INET,
|
|
384
|
+
user_agent TEXT,
|
|
385
|
+
metadata JSONB
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
CREATE INDEX idx_consent_user ON consent_records(user_id);
|
|
389
|
+
CREATE INDEX idx_consent_session ON consent_records(session_id);
|
|
390
|
+
CREATE INDEX idx_consent_type ON consent_records(consent_type);
|
|
391
|
+
```
|
|
392
|
+
|
|
393
|
+
### `POST /consent/grant` endpoint template
|
|
394
|
+
|
|
395
|
+
```typescript
|
|
396
|
+
// firebase/functions/src/modules/consent/consent.functions.ts
|
|
397
|
+
export async function grantConsent(req: Request, res: Response) {
|
|
398
|
+
const { consent_type, version, granted } = req.body;
|
|
399
|
+
|
|
400
|
+
// Validate consent_type against allowlist
|
|
401
|
+
const validTypes = [
|
|
402
|
+
"cookies_essential",
|
|
403
|
+
"cookies_analytics",
|
|
404
|
+
"cookies_marketing",
|
|
405
|
+
"newsletter",
|
|
406
|
+
"data_processing",
|
|
407
|
+
];
|
|
408
|
+
if (!validTypes.includes(consent_type))
|
|
409
|
+
return res.status(400).json({ error: "invalid consent_type" });
|
|
410
|
+
|
|
411
|
+
await db.query(
|
|
412
|
+
`
|
|
413
|
+
INSERT INTO consent_records (user_id, session_id, consent_type, version, granted, ip_address, user_agent)
|
|
414
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7)
|
|
415
|
+
`,
|
|
416
|
+
[
|
|
417
|
+
req.user?.id ?? null,
|
|
418
|
+
req.headers["x-session-id"],
|
|
419
|
+
consent_type,
|
|
420
|
+
version,
|
|
421
|
+
granted,
|
|
422
|
+
req.ip,
|
|
423
|
+
req.headers["user-agent"],
|
|
424
|
+
],
|
|
425
|
+
);
|
|
426
|
+
|
|
427
|
+
res.json({ ok: true });
|
|
428
|
+
}
|
|
429
|
+
```
|
|
430
|
+
|
|
431
|
+
---
|
|
432
|
+
|
|
433
|
+
## Related skills
|
|
434
|
+
|
|
435
|
+
- **`engineering-audit`** — security axis includes LGPD checks (high-level)
|
|
436
|
+
- **`database-provision`** — `consent_records` table schema reference
|
|
437
|
+
- **`audit-logging-middleware`** (Tier 3 roadmap) — provides the audit_logs coverage required by Phase 5
|
|
438
|
+
- **`incident-response-runbook`** (Tier 3 roadmap) — provides the breach response template required by Phase 6
|
|
439
|
+
- **`secret-safe-commit`** — prevents PII leaks via committed credentials
|
|
440
|
+
|
|
441
|
+
---
|
|
442
|
+
|
|
443
|
+
## References
|
|
444
|
+
|
|
445
|
+
- [Lei nº 13.709/2018 (LGPD) — full text](https://www.planalto.gov.br/ccivil_03/_ato2015-2018/2018/lei/l13709.htm)
|
|
446
|
+
- [ANPD — Autoridade Nacional de Proteção de Dados](https://www.gov.br/anpd/pt-br)
|
|
447
|
+
- [Guia ANPD para tratamento de dados pessoais por agentes de tratamento de pequeno porte](https://www.gov.br/anpd/pt-br/documentos-e-publicacoes/guia-tratamento-pequeno-porte.pdf)
|
|
448
|
+
- [Comparison LGPD vs GDPR](https://www.privacy.com.br/blog/lgpd-x-gdpr) — most patterns transfer
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: load-testing
|
|
3
|
+
description: Load-test HTTP APIs with Locust. Produces p50/p95/p99 latency, error rate, and regression-vs-baseline verdicts. Primary target v0.1 is the Gestao Merlin Dashboard API.
|
|
4
|
+
license: Apache-2.0
|
|
5
|
+
compatibility: Requires Python 3.9+ and locust>=2.43. Install with 'pip install -r .merlin-core/skills/general/load-testing/requirements.txt'.
|
|
6
|
+
metadata:
|
|
7
|
+
author: merlin-framework
|
|
8
|
+
version: "0.1.0"
|
|
9
|
+
auto_activate: [load-test, locust, p95-latency, benchmark-api]
|
|
10
|
+
file_triggers:
|
|
11
|
+
[
|
|
12
|
+
"locustfile*.py",
|
|
13
|
+
".merlin-core/skills/general/load-testing/**",
|
|
14
|
+
"tests/benchmarks/baseline.*.json",
|
|
15
|
+
]
|
|
16
|
+
tool_reminders:
|
|
17
|
+
[
|
|
18
|
+
Locust is NOT stdlib — install via requirements.txt before running,
|
|
19
|
+
Dashboard API has no auth — do NOT add Bearer tokens to the Dashboard locustfile,
|
|
20
|
+
v0.1 targets Dashboard API GET endpoints only (POSTs have side effects and are deferred),
|
|
21
|
+
Always run headless in CI — use --headless with -u -r -t flags,
|
|
22
|
+
]
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
# Load Testing with Locust
|
|
26
|
+
|
|
27
|
+
Load-testing skill for verifying HTTP API performance under concurrent user load. Produces latency percentiles, error rates, and regression-vs-baseline verdicts for Quinn's quality pipeline.
|
|
28
|
+
|
|
29
|
+
## Decision Tree: When to Run a Load Test
|
|
30
|
+
|
|
31
|
+
```
|
|
32
|
+
Does the PR touch dashboard/backend/src/routes/**?
|
|
33
|
+
YES → Run load test before Quinn's final verdict
|
|
34
|
+
NO → Does the PR add a new HTTP endpoint anywhere?
|
|
35
|
+
YES → Add a task for it in locustfile_dashboard.py, then run
|
|
36
|
+
NO → Skip load testing
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Docs-only, frontend-only, and pure-refactor PRs that don't change API behavior can skip load tests.
|
|
40
|
+
|
|
41
|
+
## Quickstart: Local Headless Run
|
|
42
|
+
|
|
43
|
+
Requires Python 3.9+ and a virtualenv:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
# Create venv (once)
|
|
47
|
+
python -m venv .merlin-core/skills/general/load-testing/.venv
|
|
48
|
+
|
|
49
|
+
# Activate (POSIX)
|
|
50
|
+
source .merlin-core/skills/general/load-testing/.venv/bin/activate
|
|
51
|
+
|
|
52
|
+
# Activate (Windows)
|
|
53
|
+
.merlin-core/skills/general/load-testing/.venv/Scripts/activate
|
|
54
|
+
|
|
55
|
+
# Install
|
|
56
|
+
pip install -r .merlin-core/skills/general/load-testing/requirements.txt
|
|
57
|
+
|
|
58
|
+
# Run (spawns the dashboard backend, runs Locust, writes reports)
|
|
59
|
+
python .merlin-core/skills/general/load-testing/scripts/run_local.py \
|
|
60
|
+
--users 100 --spawn-rate 10 --runtime 3m
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Outputs land in `.ai/load-tests/<ISO-timestamp>/`:
|
|
64
|
+
|
|
65
|
+
- `run_stats.csv`, `run_failures.csv`, `run_stats_history.csv` — raw Locust CSVs
|
|
66
|
+
- `report.html` — per-endpoint latency dashboard
|
|
67
|
+
- Plus a symlink-or-copy `.ai/load-tests/LATEST.json` consumed by the Layer 2 PR gate
|
|
68
|
+
|
|
69
|
+
## Quickstart: Docker Compose Run
|
|
70
|
+
|
|
71
|
+
Reproducible run in three containers (dashboard + locust master + 1 worker):
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
docker compose -f .merlin-core/skills/general/load-testing/docker/docker-compose.locust.yml up --build
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Locust UI becomes available at `http://localhost:8089` with host pre-filled to `http://app:3939`.
|
|
78
|
+
|
|
79
|
+
## Scripting a New Target
|
|
80
|
+
|
|
81
|
+
Copy `templates/locustfile_dashboard.py` as your starting point. Each task is a method decorated with `@task(weight)` — higher weights run more often. Always:
|
|
82
|
+
|
|
83
|
+
1. Use the `name=` kwarg on `self.client.get(...)` to group requests by endpoint (not by path-with-IDs).
|
|
84
|
+
2. Import `threshold_hook` at the top (it installs the `@events.quitting` listener that enforces p95/error-rate gates).
|
|
85
|
+
3. Set `host` to the default target URL.
|
|
86
|
+
|
|
87
|
+
## Thresholds & Baselines
|
|
88
|
+
|
|
89
|
+
**Thresholds** (configured via env vars, enforced by `threshold_hook.py`):
|
|
90
|
+
|
|
91
|
+
| Env var | Default | Meaning |
|
|
92
|
+
| ----------------------- | ------- | ---------------------------------------------------- |
|
|
93
|
+
| `LOCUST_P95_MAX_MS` | 1500 | Exit non-zero if total-suite p95 exceeds this |
|
|
94
|
+
| `LOCUST_ERROR_RATE_MAX` | 0.01 | Exit non-zero if total-suite error rate exceeds this |
|
|
95
|
+
|
|
96
|
+
**Regressions** (enforced by `compare_baseline.py`):
|
|
97
|
+
|
|
98
|
+
- Per-endpoint: `delta = (current_p95 - baseline_p95) / baseline_p95`
|
|
99
|
+
- Ignored if `baseline_p95_ms < 50` (noise floor — too volatile on shared CI runners)
|
|
100
|
+
- FAIL if any eligible endpoint has `delta > 0.20` (20%)
|
|
101
|
+
|
|
102
|
+
See `tests/benchmarks/README.md` for baseline management.
|
|
103
|
+
|
|
104
|
+
## Integration with Quinn (QA Agent)
|
|
105
|
+
|
|
106
|
+
Quinn invokes this skill when a PR changes `dashboard/backend/src/routes/**` or adds a new API route. She emits one of three verdicts based on `.ai/load-tests/LATEST.json`:
|
|
107
|
+
|
|
108
|
+
- **PASS** — all thresholds met AND `regression_ok === true`
|
|
109
|
+
- **CONDITIONAL PASS** — thresholds met, regression delta 10–20% on any endpoint
|
|
110
|
+
- **FAIL** — threshold breach OR regression > 20%
|
|
111
|
+
|
|
112
|
+
## Integration with Layer 2 PR Gate
|
|
113
|
+
|
|
114
|
+
`.merlin-core/core/quality-gates/layer2-pr-automation.js` reads `.ai/load-tests/LATEST.json` when present. If the file exists, a `load-test-regression` check is added to the PR gate. Absent file → no check added (backwards-compatible).
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
FROM node:22-alpine
|
|
2
|
+
WORKDIR /app
|
|
3
|
+
|
|
4
|
+
# Copy workspace manifests first for layer caching
|
|
5
|
+
COPY dashboard/package.json dashboard/package-lock.json ./dashboard/
|
|
6
|
+
COPY dashboard/backend/package.json ./dashboard/backend/
|
|
7
|
+
COPY dashboard/shared/package.json ./dashboard/shared/
|
|
8
|
+
|
|
9
|
+
RUN cd dashboard && npm ci --omit=dev
|
|
10
|
+
|
|
11
|
+
# Copy source
|
|
12
|
+
COPY dashboard/backend ./dashboard/backend
|
|
13
|
+
COPY dashboard/shared ./dashboard/shared
|
|
14
|
+
|
|
15
|
+
WORKDIR /app/dashboard/backend
|
|
16
|
+
RUN npm run build
|
|
17
|
+
|
|
18
|
+
ENV PORT=3939
|
|
19
|
+
ENV NODE_ENV=test
|
|
20
|
+
EXPOSE 3939
|
|
21
|
+
CMD ["node", "dist/index.js"]
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
services:
|
|
2
|
+
app:
|
|
3
|
+
build:
|
|
4
|
+
context: ../../../../..
|
|
5
|
+
dockerfile: .merlin-core/skills/general/load-testing/docker/Dockerfile.dashboard
|
|
6
|
+
ports:
|
|
7
|
+
- "3939:3939"
|
|
8
|
+
environment:
|
|
9
|
+
- NODE_ENV=test
|
|
10
|
+
- PORT=3939
|
|
11
|
+
|
|
12
|
+
locust-master:
|
|
13
|
+
image: locustio/locust:2.43.4
|
|
14
|
+
ports:
|
|
15
|
+
- "8089:8089"
|
|
16
|
+
volumes:
|
|
17
|
+
- ../templates:/mnt/locust:ro
|
|
18
|
+
- ./results:/mnt/results
|
|
19
|
+
environment:
|
|
20
|
+
- PYTHONPATH=/mnt/locust
|
|
21
|
+
command: >
|
|
22
|
+
-f /mnt/locust/locustfile_dashboard.py
|
|
23
|
+
--master
|
|
24
|
+
--host http://app:3939
|
|
25
|
+
depends_on:
|
|
26
|
+
- app
|
|
27
|
+
|
|
28
|
+
locust-worker:
|
|
29
|
+
image: locustio/locust:2.43.4
|
|
30
|
+
volumes:
|
|
31
|
+
- ../templates:/mnt/locust:ro
|
|
32
|
+
environment:
|
|
33
|
+
- PYTHONPATH=/mnt/locust
|
|
34
|
+
command: >
|
|
35
|
+
-f /mnt/locust/locustfile_dashboard.py
|
|
36
|
+
--worker
|
|
37
|
+
--master-host locust-master
|
|
38
|
+
depends_on:
|
|
39
|
+
- locust-master
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
locust>=2.43,<3.0
|