@polymorphism-tech/morph-spec 8.45.0 → 8.47.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.md +6 -5
- package/README.md +2 -2
- package/bin/morph-spec.js +2 -4
- package/bin/validate.js +4 -25
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +2 -2
- package/docs/QUICKSTART.md +1 -1
- package/framework/CLAUDE.md +2 -2
- package/framework/MORPH.md +9 -9
- package/framework/commands/create-umbraco-lp.md +2 -0
- package/framework/commands/migrate-lp-to-umbraco.md +2 -0
- package/framework/commands/morph-archive.md +1 -1
- package/framework/commands/morph-hotfix.md +1 -1
- package/framework/commands/morph-infra.md +17 -203
- package/framework/commands/morph-media.md +3 -0
- package/framework/commands/morph-preflight.md +5 -28
- package/framework/commands/morph-proposal.md +2 -2
- package/framework/commands/morph-troubleshoot.md +2 -14
- package/framework/docs/CLI.md +8 -7
- package/framework/hooks/claude-code/core/state-sync.js +13 -1
- package/framework/hooks/shared/e2e-check.js +3 -4
- package/framework/hooks/shared/state-writer.js +1 -0
- package/framework/rules/ai-agents-standards.md +18 -16
- package/framework/rules/asaas-standards.md +3 -1
- package/framework/rules/csharp-standards.md +10 -8
- package/framework/rules/data-standards.md +5 -5
- package/framework/rules/dotnet-templates.md +1 -1
- package/framework/rules/frontend-standards.md +4 -2
- package/framework/rules/gsap-standards.md +10 -5
- package/framework/rules/hangfire-standards.md +3 -1
- package/framework/rules/infrastructure-standards.md +4 -2
- package/framework/rules/morph-workflow.md +2 -2
- package/framework/rules/neon-auth-standards.md +3 -1
- package/framework/rules/neon-standards.md +6 -4
- package/framework/rules/nextjs-standards.md +13 -11
- package/framework/rules/nextjs-templates.md +1 -1
- package/framework/rules/resend-standards.md +3 -1
- package/framework/schemas/config.schema.json +4 -0
- package/framework/schemas/feature.schema.json +4 -4
- package/framework/skills/README.md +1 -1
- package/framework/skills/core/create-umbraco-lp/SKILL.md +3 -3
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +3 -3
- package/framework/skills/core/morph-apply/SKILL.md +3 -3
- package/framework/skills/core/morph-brainstorming/SKILL.md +3 -3
- package/framework/skills/core/morph-hotfix/SKILL.md +4 -4
- package/framework/skills/core/morph-implement/SKILL.md +3 -3
- package/framework/skills/core/morph-machine/SKILL.md +3 -3
- package/framework/skills/core/morph-media/SKILL.md +3 -3
- package/framework/skills/core/morph-plan/SKILL.md +3 -3
- package/framework/skills/core/morph-proposal/SKILL.md +3 -3
- package/framework/skills/core/morph-review/SKILL.md +30 -17
- package/framework/skills/core/morph-stack-scan/SKILL.md +3 -3
- package/framework/skills/core/morph-standards/SKILL.md +6 -6
- package/framework/skills/core/morph-uiux/SKILL.md +3 -3
- package/framework/standards/STANDARDS.json +59 -56
- package/framework/standards/ai-agents/evals-with-cache.md +1 -1
- package/framework/standards/ai-agents/llm-runtime-defaults.md +1 -1
- package/framework/standards/ai-agents/modalities-speech-to-text.md +36 -26
- package/framework/standards/ai-agents/prompt-sources.md +6 -4
- package/framework/standards/ai-agents/providers/model-registry.md +1 -1
- package/framework/standards/ai-agents/rag-custom-pgvector.md +67 -39
- package/framework/standards/ai-agents/setup.md +1 -1
- package/framework/standards/ai-agents/structured-output.md +1 -1
- package/framework/standards/ai-agents/sweet-spot.md +1 -1
- package/framework/standards/architecture/code-comments.md +2 -2
- package/framework/standards/architecture/vertical-slice/vertical-slice.md +18 -9
- package/framework/standards/backend/api/validation.md +135 -47
- package/framework/standards/backend/database/postgresql/database.md +11 -7
- package/framework/standards/backend/database/vector-search-rag.md +207 -324
- package/framework/standards/backend/dotnet/fluent-validation-vsa.md +14 -8
- package/framework/standards/backend/dotnet/result-pattern.md +40 -6
- package/framework/standards/backend/dotnet/scalar-ui.md +13 -7
- package/framework/standards/backend/dotnet/scrutor.md +1 -1
- package/framework/standards/backend/dotnet/testing.md +1 -1
- package/framework/standards/backend/dotnet/vsa-handler-patterns.md +7 -7
- package/framework/standards/backend/integrations/asaas/asaas-api.md +309 -165
- package/framework/standards/backend/integrations/hangfire/hangfire-jobs.md +134 -154
- package/framework/standards/data/nosql/cache/redis.md +120 -44
- package/framework/standards/data/nosql/cosmos-db.md +114 -71
- package/framework/standards/frontend/design-system/animations.md +1 -1
- package/framework/standards/frontend/design-system/naming.md +1 -1
- package/framework/standards/frontend/nextjs/motion-patterns.md +45 -29
- package/framework/standards/frontend/nextjs/naming-conventions.md +1 -1
- package/framework/standards/infrastructure/docker/coolify-deploy.md +8 -6
- package/framework/standards/infrastructure/neon/neon-pgvector.md +120 -75
- package/framework/standards/infrastructure/neon/neon-setup.md +53 -31
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +2 -2
- package/framework/templates/code/dotnet/extensions/database-extensions.cs +1 -1
- package/framework/templates/code/dotnet/extensions/result-extensions.cs +27 -0
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +2 -2
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +1 -1
- package/framework/templates/infrastructure/docker/coolify.template.json +3 -3
- package/framework/templates/infrastructure/github/README.md +2 -1
- package/framework/templates/infrastructure/github/workflows/deploy-coolify.yml.hbs +2 -1
- package/package.json +1 -1
- package/src/commands/observability/telemetry.js +3 -5
- package/src/commands/project/init.js +2 -1
- package/src/commands/project/update.js +16 -18
- package/src/commands/state/approve.js +17 -0
- package/src/commands/state/gate-check.js +4 -14
- package/src/commands/validation/verify.js +99 -57
- package/src/core/paths/output-schema.js +1 -1
- package/src/dashboard/app/App.jsx +0 -2
- package/src/dashboard/app/components/CommandPalette.jsx +2 -3
- package/src/dashboard/app/components/EntityLink.jsx +0 -1
- package/src/dashboard/app/components/Markdown.jsx +1 -1
- package/src/dashboard/app/components/Sidebar.jsx +1 -2
- package/src/dashboard/app/pages/RulesMap.jsx +3 -3
- package/src/dashboard/app/pages/SkillsLibrary.jsx +3 -3
- package/src/dashboard/scanner/activity-scanner.js +1 -1
- package/src/dashboard/scanner/docs-scanner.js +5 -23
- package/src/dashboard/scanner/features-scanner.js +1 -1
- package/src/dashboard/scanner/index.js +0 -2
- package/src/dashboard/scanner/rules-scanner.js +15 -10
- package/src/dashboard/scanner/skills-scanner.js +2 -3
- package/src/lib/ci/ci-verify.js +118 -0
- package/src/lib/ci/github-ci.js +192 -0
- package/src/lib/ci/workflow-scaffold.js +122 -0
- package/src/lib/evaluator-report.js +13 -0
- package/src/lib/risk-detector.js +8 -0
- package/src/lib/stack/stack-profile.js +1 -1
- package/src/lib/telemetry/verify-event.js +3 -2
- package/src/lib/validators/reuse/reuse-validator.js +2 -3
- package/src/lib/validators/reuse/symbol-scanner.js +2 -4
- package/src/lib/validators/validation-runner.js +8 -88
- package/src/lib/validators/verify-runner.js +22 -72
- package/src/scripts/setup-infra.js +33 -22
- package/src/utils/agents-installer.js +20 -8
- package/src/utils/file-copier.js +7 -5
- package/framework/commands/commit.md +0 -166
- package/framework/hooks/claude-code/__pycache__/statusline.cpython-313.pyc +0 -0
- package/framework/rubrics/backend.json +0 -41
- package/framework/rubrics/default.json +0 -36
- package/framework/rubrics/frontend.json +0 -36
- package/framework/templates/project/validate.js +0 -97
- package/src/dashboard/app/pages/Rubrics.jsx +0 -97
- package/src/dashboard/scanner/rubrics-scanner.js +0 -12
- package/src/lib/validators/architecture/architecture-validator.js +0 -270
- package/src/lib/validators/architecture/index.js +0 -7
- package/src/lib/validators/css/css-validator.js +0 -340
- package/src/lib/validators/css/index.js +0 -7
- package/src/lib/validators/design-system/design-system-validator.js +0 -237
- package/src/lib/validators/design-system/index.js +0 -7
- package/src/lib/validators/score-aggregator.js +0 -244
- package/src/lib/validators/ui/index.js +0 -7
- package/src/lib/validators/ui/ui-contrast-validator.js +0 -422
|
@@ -8,11 +8,13 @@ stacks:
|
|
|
8
8
|
|
|
9
9
|
# C# and .NET VSA Standards
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
11
|
+
- **architecture-vertical-slice-vertical-slice** (`architecture/vertical-slice/vertical-slice.md`) — Uma slice por operação em `Features/{Entity}Feature/{Verb}{Entity}/`: Request/Response `sealed record`, Handler, Validator e Endpoint `IApiEndpoint` `internal sealed`. Decorators Scrutor: Logging → Validation → Handler. PROIBIDO: MediatR/`IRequest`, AggregateRoot, DomainEvent, CQRS formal, camada Application Service, DTO compartilhado entre features, `IRepository<T>`/`IUnitOfWork`.
|
|
12
|
+
- **backend-dotnet-vsa-handler-patterns** (`backend/dotnet/vsa-handler-patterns.md`) — Handler `sealed class` com primary constructor implementando `IHandler<TRequest, TResponse>` (não MediatR): injeta `ApplicationDbContext` direto, usa `Guid.CreateVersion7()` (nunca `Guid.NewGuid()`), passa `CancellationToken` em tudo e devolve `Result<T>`. Erros em `{Feature}Errors.cs`. SQL cru ou store dedicado só com justificativa em `decisions.md`.
|
|
13
|
+
- **backend-dotnet-result-pattern** (`backend/dotnet/result-pattern.md`) — Falha esperada é `Result`/`Result<T>`, nunca exceção. Endpoint: `result.Match(value => Results.Ok(value), error => error.ToHttpResult())`; nunca leia `.Value` fora do `Match`. Status pelo `ErrorType` (Validation 400, NotFound 404, Conflict 409, Unauthorized 401, Forbidden 403, Unexpected 500), nunca BadRequest para tudo. PROIBIDO: try/catch no handler, retornar null, erro string sem código.
|
|
14
|
+
- **backend-dotnet-fluent-validation-vsa** (`backend/dotnet/fluent-validation-vsa.md`) — Um `sealed AbstractValidator<TRequest>` (FluentValidation 12) por request, na pasta da slice; o `ValidationDecorator` roda antes do handler e devolve `Result.Failure(ValidationError)`. `AddValidatorsFromAssembly()` ANTES de `AddHandlersFromAssembly()`. Sempre `.WithMessage()`; tempo via `TimeProvider` lido DENTRO da regra. Nunca lance `ValidationException`.
|
|
15
|
+
- **backend-dotnet-scrutor** (`backend/dotnet/scrutor.md`) — `AddHandlersFromAssembly` registra cada `IHandler<,>` como Scoped (filtro `!t.ContainsGenericParameters`) e depois `Decorate` Validation e então Logging (o último registrado é o mais externo). Endpoints `IApiEndpoint` via `TryAddEnumerable` Transient + `MapApiEndpoints`. Nunca registre handler um a um.
|
|
16
|
+
- **backend-dotnet-scalar-ui** (`backend/dotnet/scalar-ui.md`) — Scalar no lugar do Swagger: `Microsoft.AspNetCore.OpenApi` 10.0.0 + `Scalar.AspNetCore` 2.12.40, nunca Swashbuckle. `MapOpenApi()` só em `IsDevelopment()` e antes de `MapScalarApiReference`. Todo endpoint com `.WithTags(ApiTags.X)` (constantes), `.Produces<T>` e `.ProducesProblem(status)` por falha possível.
|
|
17
|
+
- **backend-api-validation** (`backend/api/validation.md`) — O validator checa só FORMA (sem DbContext); existência, unicidade e estado ficam no handler com `{Entity}Errors` tipados. Checagem de estado valida o INVÁLIDO (enum ordenado, estados de erro em 100+). PROIBIDO: lançar exceção, validar na lambda do endpoint, misturar DataAnnotations, `if (status != Expected)`, switch exaustivo sobre estados válidos.
|
|
18
|
+
- **architecture-code-comments** (`architecture/code-comments.md`) — Padrão é nenhum comentário: renomeie, extraia, tipe ou teste antes. Só o porquê que o código não mostra (invariante, ordem, quirk externo com link), até ~3 linhas. PROIBIDO: história de processo (task, UC, ADR, Gate), repetir o código, XML doc/JSDoc que repete a assinatura, banner, `#region`, código comentado, TODO solto. O hook `comment-guard` bloqueia.
|
|
19
|
+
|
|
20
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
paths:
|
|
3
3
|
- "**/*Cache*.cs"
|
|
4
4
|
- "**/*Redis*.cs"
|
|
5
|
-
- "**/*Cosmos*.cs"
|
|
6
5
|
- "**/*Vector*.cs"
|
|
7
6
|
- "**/*Embedding*.cs"
|
|
8
7
|
- "**/*Rag*.cs"
|
|
@@ -12,7 +11,8 @@ stacks:
|
|
|
12
11
|
|
|
13
12
|
# Data & Cache Standards
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
- **data-nosql-cache-redis** (`data/nosql/cache/redis.md`) — Cache distribuído, nunca store primário. `Microsoft.Extensions.Caching.StackExchangeRedis` 10.0.12; `IConnectionMultiplexer` singleton LAZY (nunca conectar no registro). Cache-aside no handler com `IDistributedCache` (sem wrapper); invalide a chave exata depois do `SaveChangesAsync`. PROIBIDO: cachear segredo/PII sem criptografia, omitir TTL, engolir `RedisConnectionException`.
|
|
15
|
+
- **data-vector-search-rag-chunking** (`data/vector-search/rag-chunking.md`) — Prosa: sentence-aware, 256 tokens; doc técnico: semântico por headers; Q&A inteiro; código: a função inteira. Overlap 10–20%, mínimo 50 e máximo ~512 tokens. Sempre grave metadados do chunk (DocumentId, ChunkIndex, Section, SourceUrl) e reindexe quando o hash do conteúdo mudar.
|
|
16
|
+
- **backend-database-vector-search-rag** (`backend/database/vector-search-rag.md`) — Slices VSA sobre EF Core 10 + pgvector: o handler injeta `ApplicationDbContext` e `IEmbeddingGenerator` direto (sem EmbeddingService/SearchService). Busca por `d.Embedding!.CosineDistance(query)` com a distância em ordem ASC. Sem documento relevante, `NotFound` antes de chamar o LLM. Indexação em lote: um `GenerateAsync` e um `SaveChanges`.
|
|
17
|
+
|
|
18
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -30,7 +30,7 @@ morph-spec scaffold dotnet book get-all-books
|
|
|
30
30
|
|
|
31
31
|
Generates 7 files: endpoint, handler, request, response, validator + entity, errors (shared at feature level). Entity/errors auto-skipped if they already exist.
|
|
32
32
|
|
|
33
|
-
**
|
|
33
|
+
**Adding a single file to an existing slice:** read its `.hbs` template (table below) and write the file following it — `scaffold` generates whole slices only, and there is no single-file render command.
|
|
34
34
|
|
|
35
35
|
## VSA Feature Templates (Vertical Slice Architecture)
|
|
36
36
|
|
|
@@ -9,5 +9,7 @@ stacks:
|
|
|
9
9
|
|
|
10
10
|
# Frontend Standards
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
- **frontend-design-system-naming** (`frontend/design-system/naming.md`) — BEM para componente reutilizável (`.card`, `.card__header`, `.card--featured`); prefixo de página para elemento específico (`.home-hero`). Custom properties em `:root` com namespace `--app-`. Estado por sufixo fixo: `--active`, `--disabled`, `--loading`, `--error`.
|
|
13
|
+
- **frontend-design-system-animations** (`frontend/design-system/animations.md`) — Classes `.animate-*`, `.duration-fast/normal/slow`, `.stagger-1..10`. Lista escalonada exige `animation-delay` E `animation-fill-mode: backwards`. Sempre o bloco `prefers-reduced-motion: reduce`. Além do CSS: Motion (`motion/react`) para enter/exit/layout; GSAP só para ScrollTrigger, SVG morph e timelines.
|
|
14
|
+
|
|
15
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
---
|
|
2
2
|
paths:
|
|
3
|
-
- "
|
|
4
|
-
- "
|
|
3
|
+
- "**/animations/**"
|
|
4
|
+
- "**/*gsap*"
|
|
5
|
+
- "**/*Gsap*"
|
|
6
|
+
- "**/*scroll-trigger*"
|
|
7
|
+
- "**/*ScrollTrigger*"
|
|
5
8
|
stacks:
|
|
6
9
|
- nextjs
|
|
7
10
|
---
|
|
8
11
|
|
|
9
12
|
# GSAP Animation Standards
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
+
- **frontend-gsap-core** (`frontend/gsap/gsap-core.md`) — GSAP 3.13 + `@gsap/react` só para ScrollTrigger, SVG morph/draw, timelines complexas e SplitText; o resto é Motion, e NUNCA os dois no mesmo elemento. Código em `'use client'` dentro de `useGSAP()` com `{ scope: containerRef }` (nunca `useEffect`). Só transform/opacity; `prefers-reduced-motion` via `gsap.matchMedia()` é obrigatório; durations/easings vêm de `@/lib/design-tokens`.
|
|
15
|
+
- **frontend-gsap-scrolltrigger** (`frontend/gsap/gsap-scrolltrigger.md`) — `gsap.registerPlugin(ScrollTrigger)` uma vez no init, nunca em `useEffect`/loop, e nunca `ScrollTrigger.create()` no escopo do módulo. Scrub com ease `'none'` (0.3–1 em produção). `pin: true` + `anticipatePin: 1`; nunca pin aninhado. `ScrollTrigger.batch` em grids de 20+. `ScrollTrigger.refresh()` após conteúdo dinâmico, troca de rota e `onLoad` de imagem.
|
|
16
|
+
- **frontend-gsap-plugins** (`frontend/gsap/gsap-plugins.md`) — Todo plugin é gratuito no pacote público `gsap` (`npm install gsap @gsap/react`); o registry privado `@gsap/shockingly` é obsoleto. Flip: `getState()` → muda o DOM → `Flip.from(...)`. SplitText com `autoSplit: true`, animando em `onSplit`. MorphSVG exige `<path>`; DrawSVG exige stroke visível; Draggable com inércia exige InertiaPlugin.
|
|
17
|
+
|
|
18
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -10,4 +10,6 @@ stacks:
|
|
|
10
10
|
|
|
11
11
|
# Hangfire Background Jobs Standards
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
- **backend-integrations-hangfire-hangfire-jobs** (`backend/integrations/hangfire/hangfire-jobs.md`) — Hangfire 1.8.25 só com razão real em `decisions.md`; o que cabe no request fica no handler. Storage `Hangfire.PostgreSql` 1.21.1 com `UseNpgsqlConnection` no endpoint DIRETO do Neon; referencie `Newtonsoft.Json` 13.0.4. Job é classe fina e idempotente que chama o handler; `[AutomaticRetry]`, sem try/catch nem retry manual. Dashboard exige Admin autenticado.
|
|
14
|
+
|
|
15
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -10,8 +10,10 @@ stacks:
|
|
|
10
10
|
|
|
11
11
|
# Infrastructure Standards
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
- **infrastructure-docker-coolify-deploy** (`infrastructure/docker/coolify-deploy.md`) — Acesso só por SSH na VPS, API do Coolify em `localhost:8000/api/v1` com token server-side (nunca impresso). Env vars no Coolify, nunca no Dockerfile. Endpoint `/health`. Redeploy por `POST /api/v1/deploy?uuid=` (GET não deploya); sem `deployment_uuid` na resposta, nada foi deployado.
|
|
14
|
+
- **infrastructure-docker-local-compose-isolation** (`infrastructure/docker/local-compose-isolation.md`) — Cada worktree roda o próprio stack compose; portas do bloco da worktree (`PORT`, `API_PORT`, `POSTGRES_PORT`, `REDIS_PORT`) publicadas como `${VAR:-default}:container`. PROIBIDO: porta fixa no host, `container_name`. Healthcheck em todo serviço. Compose que lê a porta por outro nome: declare em `e2e.portEnvNames`.
|
|
15
|
+
|
|
16
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
15
17
|
|
|
16
18
|
## Infrastructure Templates
|
|
17
19
|
|
|
@@ -48,7 +48,7 @@ The full slash-command and CLI surface lives in the resident `.claude/CLAUDE.md`
|
|
|
48
48
|
|
|
49
49
|
| Path | Notes |
|
|
50
50
|
|------|-------|
|
|
51
|
-
| `.morph/features/{feature}/feature.json` | **Authoritative + committed** feature state. Write it through the CLI (`create`, `
|
|
51
|
+
| `.morph/features/{feature}/feature.json` | **Authoritative + committed** feature state. Write it through the CLI (`create`, `gate-decision`, `gate-check`, `approve`) — a hand Edit collides with the `state-sync` hook |
|
|
52
52
|
| `.morph/state.json` | **READ-ONLY** — thin, gitignored index rebuilt from `feature.json` on load; kept in sync by the `state-sync` hook |
|
|
53
53
|
| `.morph/features/{feature}/{phase}/` | Feature outputs organized by phase |
|
|
54
54
|
| `.morph/framework/` | **READ-ONLY** — framework files managed by morph-spec |
|
|
@@ -198,7 +198,7 @@ fix** — never a patch on the symptom. This is MANDATORY:
|
|
|
198
198
|
1. Reproduce it and read the full error, not the first line.
|
|
199
199
|
2. For a known .NET/Next.js error, run `/morph-troubleshoot <keywords>` first.
|
|
200
200
|
3. One hypothesis at a time, each tested by the smallest check that could refute it.
|
|
201
|
-
4. After three failed fixes,
|
|
201
|
+
4. After three failed fixes, never try a fourth on your own: escalate via `AskUserQuestion` (accept / keep trying / skip), bringing the design question the failures raise — a fourth attempt with no new information repeats the error (same rule as MORPH.md §0).
|
|
202
202
|
5. Confirm the fix with the same check that reproduced the bug; add a test only when no existing one covers that behavior.
|
|
203
203
|
|
|
204
204
|
Everything else that a rule like this might list is owned by the flow itself, and duplicating it
|
|
@@ -10,4 +10,6 @@ stacks:
|
|
|
10
10
|
|
|
11
11
|
# Neon Auth Standards
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
- **backend-integrations-neon-auth-neon-auth** (`backend/integrations/neon-auth/neon-auth.md`) — SDK `@neondatabase/auth`: `createNeonAuth()` no server, `createAuthClient()` no client, `auth.middleware()` com `runtime='nodejs'`. Duas constantes de prefixo (`BACKEND_API_PREFIX`/`PROXY_API_PREFIX`), nunca uma só. O front não consulta o Neon para dado de negócio. .NET: token EdDSA/Ed25519, verificado pelo JWKS com BouncyCastle + `SignatureValidator` devolvendo `JsonWebToken`.
|
|
14
|
+
|
|
15
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -10,10 +10,12 @@ stacks:
|
|
|
10
10
|
|
|
11
11
|
# Neon PostgreSQL Standards
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
- **infrastructure-neon-setup** (`infrastructure/neon/neon-setup.md`) — Duas connection strings: `DefaultConnection` (pooled `-pooler`) para a app e `MigrationConnection` (direta) para migrations e advisory locks; nunca commitadas (user-secrets / env do Coolify). Formato keyword (`Host=...;SSL Mode=Require`), não URI. `EnableRetryOnFailure(5, 10s)` por causa do scale-to-zero. Branch sempre com `--expires-at`.
|
|
14
|
+
- **infrastructure-neon-pgvector** (`infrastructure/neon/neon-pgvector.md`) — `Npgsql.EntityFrameworkCore.PostgreSQL` 10.0.3 + `Pgvector.EntityFrameworkCore` 0.3.0; coluna `Vector` (`vector(1536)`) e `UseVector()` no `UseNpgsql`. SEMPRE índice HNSW com operator class casando a função LINQ (senão seq scan); distância em ordem ASC. PROIBIDO: DocumentRepository, SQL cru do C# sem `decisions.md`, default `gen_random_uuid()`.
|
|
15
|
+
- **infrastructure-neon-pgrag** (`infrastructure/neon/neon-pgrag.md`) — A extensão `rag` é EXPERIMENTAL: protótipo e RAG só-SQL, não produção sem teste. Nunca misture modelos de embedding numa coluna (bge-small 384 × text-embedding-3-small 1536). Índice HNSW depois da carga inicial. Produção .NET com lógica própria: tool MAF tipada sobre pgvector.
|
|
16
|
+
- **backend-integrations-neon-auth-neon-auth** (`backend/integrations/neon-auth/neon-auth.md`) — SDK `@neondatabase/auth`: `createNeonAuth()` no server, `createAuthClient()` no client, `auth.middleware()` com `runtime='nodejs'`. Duas constantes de prefixo (`BACKEND_API_PREFIX`/`PROXY_API_PREFIX`), nunca uma só. O front não consulta o Neon para dado de negócio. .NET: token EdDSA/Ed25519, verificado pelo JWKS com BouncyCastle + `SignatureValidator` devolvendo `JsonWebToken`.
|
|
17
|
+
|
|
18
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
17
19
|
|
|
18
20
|
## SQL Templates
|
|
19
21
|
|
|
@@ -8,14 +8,16 @@ stacks:
|
|
|
8
8
|
|
|
9
9
|
# Next.js Standards
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
- **frontend-nextjs-naming-conventions** (`frontend/nextjs/naming-conventions.md`) — Arquivo SEMPRE kebab-case (`user-card.tsx`); export PascalCase para componente e `useX` para hook. Zod em `.schemas.ts`, tipos em `.types.ts` via `z.infer`. Named export (só `page.tsx` usa `default`). Nunca misture casos na mesma categoria.
|
|
12
|
+
- **frontend-nextjs-project-structure** (`frontend/nextjs/project-structure.md`) — `src/app/` só roteia e importa de `features/`. Cada `src/features/{f}/` tem `components/`, `hooks/`, `types/` e `index.ts` como API pública (import de `@/features/users`, nunca deep path). NUNCA uma feature importa outra; `components/ui/` é shadcn e não se edita.
|
|
13
|
+
- **frontend-nextjs-app-router** (`frontend/nextjs/app-router.md`) — Server Component por padrão; `'use client'` só para interação, browser API ou TanStack Query. Nunca fetch em `useEffect`. `loading.tsx`/`error.tsx` ao lado do `page.tsx` (`error.tsx` é client). Server Component chama o .NET com `BACKEND_API_PREFIX`; evite `route.ts`.
|
|
14
|
+
- **frontend-nextjs-components** (`frontend/nextjs/components.md`) — `components/ui/` é saída do shadcn CLI (nunca editar; envolva em `components/`); `components/` sem regra de negócio e sem importar `features/`; `features/*/components/` conhece o domínio. Props tipadas e validadas com Zod, sempre com `className` opcional.
|
|
15
|
+
- **frontend-nextjs-data-fetching** (`frontend/nextjs/data-fetching.md`) — Server Component com `BACKEND_API_PREFIX`; Client Component só pelo proxy same-origin com `PROXY_API_PREFIX`. TanStack Query 5 com key factory por feature e `invalidateQueries({ queryKey })`; toda resposta passa por Zod. PROIBIDO: `useEffect(() => fetch…)` e paginar/filtrar a coleção inteira no browser.
|
|
16
|
+
- **frontend-nextjs-forms** (`frontend/nextjs/forms.md`) — react-hook-form + Zod (`zodResolver`) + Field do shadcn via `Controller`; tipo por `z.infer`; nunca `useState` por campo. Submit por `useMutation`, erro em `root`. Edição reusa o schema de criação (`.partial()`). Zod 4: `z.email()`.
|
|
17
|
+
- **frontend-nextjs-state-management** (`frontend/nextjs/state-management.md`) — Estado de servidor no TanStack Query, nunca copiado para `useState`. Página, ordenação, filtros e aba ativa na URL (`searchParams`). Context só para tema, usuário ou locale. NUNCA Zustand/Redux antes de esgotar Server Components + TanStack Query.
|
|
18
|
+
- **frontend-nextjs-testing** (`frontend/nextjs/testing.md`) — Vitest + Testing Library; MSW para API; Playwright para e2e. Teste comportamento, não implementação. Orçamento: um teste por pós-condição + um de regressão por bug; cenários do mesmo comportamento em `it.each`; nada de teste que só confere string de copy.
|
|
19
|
+
- **frontend-nextjs-nextjs-patterns** (`frontend/nextjs/nextjs-patterns.md`) — Route Handler é BFF: `auth.getSession()` (401 sem sessão) e delega ao .NET; banco NUNCA em route handler. Zod no client e no server (`safeParse`, 400). `strict: true` + `noUncheckedIndexedAccess`; sem `any` em resposta de API. shadcn via `npx shadcn@latest add`.
|
|
20
|
+
- **frontend-nextjs-motion-patterns** (`frontend/nextjs/motion-patterns.md`) — Motion via `motion/react` (nunca `framer-motion` junto). Variants em `motion/variants.ts` com durations/easings de `@/lib/design-tokens`. `useReducedMotion()` obrigatório; o `layout.tsx` raiz segue Server Component. 3–5 momentos de motion por página; cena guiada por scroll é do GSAP, nunca no mesmo elemento.
|
|
21
|
+
- **architecture-code-comments** (`architecture/code-comments.md`) — Padrão é nenhum comentário: renomeie, extraia, tipe ou teste antes. Só o porquê que o código não mostra (invariante, ordem, quirk externo com link), até ~3 linhas. PROIBIDO: história de processo (task, UC, ADR, Gate), repetir o código, XML doc/JSDoc que repete a assinatura, banner, `#region`, código comentado, TODO solto. O hook `comment-guard` bloqueia.
|
|
22
|
+
|
|
23
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -27,7 +27,7 @@ morph-spec scaffold nextjs user-profile
|
|
|
27
27
|
|
|
28
28
|
Generates 4 files: page (Server Component), list component, form component, TanStack Query hook.
|
|
29
29
|
|
|
30
|
-
**
|
|
30
|
+
**Adding a single file to an existing feature:** read its `.hbs` template (table below) and write the file following it — `scaffold` generates whole features only, and there is no single-file render command.
|
|
31
31
|
|
|
32
32
|
| Template | Path | Purpose |
|
|
33
33
|
|----------|------|---------|
|
|
@@ -9,4 +9,6 @@ stacks:
|
|
|
9
9
|
|
|
10
10
|
# Resend Email Standards
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
- **backend-integrations-resend-resend-email** (`backend/integrations/resend/resend-email.md`) — REST API, não SMTP. Next: `resend` + React Email, um cliente em `lib/resend.ts`; .NET: pacote `Resend` com `AddHttpClient<ResendClient>()`. Envio sempre assíncrono (Hangfire), retry com Polly. Webhook Svix: verifique o corpo CRU com `resend.webhooks.verify()`, nunca HMAC na mão. Domínio verificado (SPF, DKIM, DMARC) antes do primeiro envio.
|
|
13
|
+
|
|
14
|
+
> Resumo injetado quando você lê ou edita um arquivo casado por `paths:`. Texto completo: `morph-spec standards --find "<id>"` e leia só a seção necessária de `.morph/framework/standards/<path>`.
|
|
@@ -9,6 +9,10 @@
|
|
|
9
9
|
"type": "object",
|
|
10
10
|
"additionalProperties": true,
|
|
11
11
|
"properties": {
|
|
12
|
+
"ci": {
|
|
13
|
+
"type": "boolean",
|
|
14
|
+
"description": "false turns `verify {f} --ci` into the local verify (with the reason printed). Absent or true: the Gate 3 proof comes from the GitHub Actions workflow that runs `morph-spec verify` (created on first use), whenever origin is GitHub and gh is authenticated."
|
|
15
|
+
},
|
|
12
16
|
"tests": {
|
|
13
17
|
"type": "array",
|
|
14
18
|
"description": "One entry per test suite. Absent (not empty) means the four-step fallback of resolveTestPlan() decides — every project created before this key existed keeps working. An empty array is an explicit declaration of 'no test suites'.",
|
|
@@ -90,7 +90,6 @@
|
|
|
90
90
|
},
|
|
91
91
|
"additionalProperties": false
|
|
92
92
|
},
|
|
93
|
-
"score": { "type": ["number", "null"], "minimum": 0, "maximum": 10 },
|
|
94
93
|
"attempts": { "type": "integer", "minimum": 1 },
|
|
95
94
|
"updatedAt": { "type": "string", "format": "date-time" }
|
|
96
95
|
},
|
|
@@ -118,7 +117,6 @@
|
|
|
118
117
|
},
|
|
119
118
|
"additionalProperties": false
|
|
120
119
|
},
|
|
121
|
-
"score": { "type": ["number", "null"], "minimum": 0, "maximum": 10 },
|
|
122
120
|
"attempts": { "type": "integer", "minimum": 1 },
|
|
123
121
|
"updatedAt": { "type": "string", "format": "date-time" }
|
|
124
122
|
},
|
|
@@ -152,7 +150,9 @@
|
|
|
152
150
|
"e2eReason": { "type": ["string", "null"], "description": "The LITERAL reason the e2e node skipped (e2e-check.js's own wording), or null when it did not skip. risk-detector.js's classifyE2eSkip() reads it: 'project does not containerize' / 'does not touch runtime' are legitimate dispensations and pass; 'docker is not available' / 'requested' (--skip-e2e) / anything unclassifiable — null included — are an absence of proof and pause Gate 3. A skip recorded WITHOUT a reason is refused on purpose: a nameless dispensation is a silent no-op." },
|
|
153
151
|
"sha": { "type": ["string", "null"], "description": "HEAD commit SHA at verify time (git rev-parse HEAD); null when not in a git repo or no commits yet." },
|
|
154
152
|
"ts": { "type": "string", "format": "date-time", "description": "Server-side timestamp, same instant as the corresponding verifications/taskVerifications entry's updatedAt." },
|
|
155
|
-
"scope": { "type": "string", "description": "'feature', or 'task:<id>' for a task-scoped verify. READ BY THE GATE, not just audit: this stamp is singular and any verify overwrites it, so a 'task:<id>' value at ship time means the last verify was NOT the feature's. risk-detector.js therefore accepts an e2e dispensation ('project'/'scope' in e2eReason) only from scope === 'feature' — a `morph-spec verify {f} {task}` of a task whose group does not touch runtime stamps exactly the legitimate-sounding reason that would otherwise buy Gate 3 for the whole feature (the last task of a feature is typically group: docs). Absent/unknown falls on the safe side, like an unclassifiable reason." }
|
|
153
|
+
"scope": { "type": "string", "description": "'feature', or 'task:<id>' for a task-scoped verify. READ BY THE GATE, not just audit: this stamp is singular and any verify overwrites it, so a 'task:<id>' value at ship time means the last verify was NOT the feature's. risk-detector.js therefore accepts an e2e dispensation ('project'/'scope' in e2eReason) only from scope === 'feature' — a `morph-spec verify {f} {task}` of a task whose group does not touch runtime stamps exactly the legitimate-sounding reason that would otherwise buy Gate 3 for the whole feature (the last task of a feature is typically group: docs). Absent/unknown falls on the safe side, like an unclassifiable reason." },
|
|
154
|
+
"source": { "type": "string", "enum": ["ci"], "description": "Present only when the stamp came from `verify --ci`: the verify --json the project CI uploaded for the pushed commit, judged by the same rules as a local run. Absent = local run." },
|
|
155
|
+
"ciRun": { "type": "string", "description": "URL of the CI run whose artifact wrote this stamp (with source: ci). `sha` is that run's headSha, so verificationStale compares the code CI saw with HEAD." }
|
|
156
156
|
},
|
|
157
157
|
"additionalProperties": false
|
|
158
158
|
},
|
|
@@ -234,7 +234,7 @@
|
|
|
234
234
|
"approved": { "type": "boolean" },
|
|
235
235
|
"timestamp": { "type": ["string", "null"], "description": "ISO timestamp of the approval/revocation, null while never evaluated." },
|
|
236
236
|
"approvedBy": { "type": ["string", "null"], "description": "\"auto\" (approve/advance --mode auto), \"manual\" (human in the loop), \"policy:{workType}\" (gate stamped at birth by `morph-spec create` per the work type's skippedGates — see src/core/work-types.js; the gate-guard hook only special-cases \"auto\", so policy-stamped gates stay silent to it), a --approver name, or null while never evaluated." },
|
|
237
|
-
"selfAssessed": { "type": "boolean", "description": "Gate `review` SOMENTE. `true` quando o Gate 3 foi aprovado sem `4-review/evaluator-report.md`, via `morph-spec approve <f> review --self-assessed`. O
|
|
237
|
+
"selfAssessed": { "type": "boolean", "description": "Gate `review` SOMENTE. `true` quando o Gate 3 foi aprovado sem `4-review/evaluator-report.md`, via `morph-spec approve <f> review --self-assessed`. O veredito deveria vir do avaliador independente; esta flag registra a degradação em vez de deixá-la silenciosa, e aparece no `morph-spec list`." }
|
|
238
238
|
},
|
|
239
239
|
"additionalProperties": true
|
|
240
240
|
}
|
|
@@ -16,7 +16,7 @@ These are the only skills the harness needs. MORPH.md references them by path.
|
|
|
16
16
|
| `morph-stack-scan` | Detect stack drift in existing projects, report in stack-scan.md | yes |
|
|
17
17
|
| `morph-plan` | Produce use cases + spec.md + tasks.json (Gate 2) | yes |
|
|
18
18
|
| `morph-implement` | Execute each task with standard + persona, auto-advance between tasks| no |
|
|
19
|
-
| `morph-review` | Final review report with
|
|
19
|
+
| `morph-review` | Final review report with SHIP/FIX verdict (Gate 3) | yes |
|
|
20
20
|
| `morph-standards` | Locate and load a specific standard on demand | no |
|
|
21
21
|
|
|
22
22
|
The legacy `level-0-meta/` and `level-1-workflows/` skill trees were removed
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: create-umbraco-lp
|
|
3
3
|
description: Guia a criação de uma landing page nova ponta-a-ponta a partir do template MORPH_Umbraco_LP_Template (Umbraco 17 + Next.js): coleta decisões, scaffolda, sobe e valida, customiza branding e módulos, e entrega checklist final.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando for iniciar um novo projeto de LP com o template Umbraco genérico
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- umbraco
|
|
10
10
|
---
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: migrate-lp-to-umbraco
|
|
3
3
|
description: Migra uma landing page existente (React/Vite, Next.js estático ou HTML) para o template Umbraco-headless MORPH_Umbraco_LP_Template entregando a LP EXATAMENTE igual à origem (mesmo CSS, imagens, fontes e comportamento) + Umbraco por cima — obtenção automática do template, inventário de seções, lift-and-rewire verbatim de cada seção para módulo editável, conexão do formulário ao backend de leads e gate de paridade determinístico. Repo-agnóstica: roda em qualquer lugar, sem template nem origem pré-baixados.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando o usuário pedir "use /migrate-lp-to-umbraco {projeto}" ou descrever a necessidade de migrar uma LP para Umbraco
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- umbraco
|
|
10
10
|
---
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-apply
|
|
3
3
|
description: Orquestra a execução autônoma de tasks de uma feature morph-spec. Analisa DAG de dependências em tasks.json e decide adaptativamente entre execução sequencial (auto-advance) ou paralela (Agent dispatch). Termina com morph-review e Gate 3.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando chegar a instrução "use /morph-apply" ou "implementar feature" com o Gate 2 aprovado
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-apply
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-brainstorming
|
|
3
3
|
description: Entende o negócio, os usuários e a arquitetura antes de qualquer planejamento técnico. Varre o ambiente primeiro, monta a árvore de decisões abertas e abre com a escolha de modo de descoberta (entrevista uma-pergunta-por-vez ou automático). Para projetos existentes, detecta desvios de stack e propõe plano de compliance.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando chegar um novo request de feature, antes de morph-plan
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-brainstorming
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-hotfix
|
|
3
3
|
description: ADW cirúrgico de hotfix — resolve uma queda/bug crítico de produção com prioridade máxima em velocidade, com aprovação humana obrigatória antes do ship.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando chegar "/morph-hotfix {feature}", quando a morph-proposal classificar o pedido como workType hotfix (Passo 0), ou quando o usuário disser "produção caiu / hotfix / urgente" a respeito de um incidente
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-hotfix
|
|
@@ -43,7 +43,7 @@ subagent_type: "morph-scout"
|
|
|
43
43
|
|
|
44
44
|
**Fallback** (se `morph-scout` não estiver registrado nos subagent types deste projeto): `general-purpose` com o campo `persona` do agente `scout` colado no prompt, **registrando o fallback nas notes da task**.
|
|
45
45
|
|
|
46
|
-
Peça ao scout: localizar o root cause provável, os arquivos afetados e o blast radius (o que mais pode quebrar). Ele é read-only (Read/Glob/Grep/Bash somente-leitura)
|
|
46
|
+
Peça ao scout: localizar o root cause provável, os arquivos afetados e o blast radius (o que mais pode quebrar). Ele é read-only (Read/Glob/Grep/Bash somente-leitura): não cole as 8 cláusulas do contrato de implementador (`morph-implement` §4 / `morph-apply` §3b) — commit `wip`, orçamento de teste e limite de tasks não se aplicam a quem não escreve. O prompt dele diz só: não escreve nem reverte nada, e o mapa é a mensagem final (Observado/Inferido, no contrato de citação que a persona já carrega). Você grava o mapa.
|
|
47
47
|
|
|
48
48
|
**Audite o mapa antes do brief.** Grave a resposta do scout em `.morph/features/{feature}/2-plan/scout-map.md` e rode `morph-spec scout-check .morph/features/{feature}/2-plan/scout-map.md --json`. Exit ≠ 0 → descarte o mapa e re-despache o scout **uma** vez com as `failures` no prompt (o mapa novo abre com o motivo); na segunda reprovação, faça você o grep do root cause e siga. Root cause e blast radius que entram no brief se conferem com grep próprio mesmo com o mapa aprovado: sob pressão de hotfix, citação inventada vira um segundo incidente.
|
|
49
49
|
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-implement
|
|
3
3
|
description: Guia a execução de cada tarefa de implementação com standard e persona adequados
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando for iniciar cada task de implementação listada em tasks.json
|
|
6
|
+
user-invocable: false
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-implement
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-machine
|
|
3
3
|
description: Cuida da RAM e da CPU da máquina enquanto o morph-spec trabalha — fila de builds e testes pesados (heavy), processos órfãos, worktrees de sub-agent que sobram. Invoque quando a máquina ou o editor estiver lento ou sem RAM, quando um comando voltar "⏳ não rodou" ou sair com exit 3 (fila cheia), quando sobrar agent-* em worktrees/, ou antes de despachar vários sub-agents que compilam ou testam em paralelo.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando a máquina estiver lenta ou sem RAM, um comando pesado esperou ou foi recusado pela fila, sobrou worktree de sub-agent, ou vários sub-agents pesados vão rodar em paralelo
|
|
6
|
+
user-invocable: false
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-machine
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-media
|
|
3
3
|
description: Conduz a AUTORIA de mídia gerada por IA — escolher o modelo pelo trabalho, montar o prompt como spec versionada, encadear derivadas a partir de um herói aprovado, subir a escada de custo e conduzir o gate humano de escolha entre N candidatas. É o lado processo; o conhecimento de API, custo e conformidade vive nos standards de mídia.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando a tarefa for PRODUZIR imagem ou vídeo por IA (catálogo, marketing, asset de LP) e alguém precisar decidir modelo, prompt e aprovação
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- dotnet
|
|
10
10
|
- nextjs
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-plan
|
|
3
3
|
description: Guia a produção dos artefatos de planejamento de uma feature (use cases, spec.md, tasks.json) e apresenta o Gate 2 trust-aware.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando a fase plan de uma feature começar, após o Gate 1 (proposal aprovado)
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-plan
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-proposal
|
|
3
3
|
description: Orquestra a fase de proposta+plano de uma feature morph-spec. Encadeia morph-brainstorming (Gate 1) e morph-plan (Gate 2). Em trust:auto pula gates sem sinais de risco.
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando o usuário pedir "use /morph-proposal" ou ao iniciar uma nova feature
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-proposal
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-review
|
|
3
3
|
description: Conduz a fase de revisão e produz o review-report.md para o Gate 3
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando a fase review começar, depois que todas as tasks de tasks.json estiverem com status `done`
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-review
|
|
@@ -37,16 +37,28 @@ Fase review, com todas as tasks `done` e o `recap.md` em dia. Normalmente chamad
|
|
|
37
37
|
- `evaluator.partial: true` (`PARCIAL` na 1ª linha): ver "PARCIAL" no passo 4.
|
|
38
38
|
- Ausente ou sem veredito: siga para o passo 3.
|
|
39
39
|
|
|
40
|
-
3. **Prova da suíte — uma rodada,
|
|
41
|
-
|
|
42
|
-
|
|
40
|
+
3. **Prova da suíte — uma rodada, no CI.** Depois da última task, commite o trabalho da feature na
|
|
41
|
+
branch (`git add <paths>` + `git commit`: o CI só vê commits) e rode
|
|
42
|
+
`morph-spec verify {feature} --ci --json` com `run_in_background`. Ele empurra `morph/{feature}`,
|
|
43
|
+
cria o workflow `morph-verify.yml` se o projeto não tem um, espera o run e grava o stamp do JSON que
|
|
44
|
+
o run publicou. Sem CI (sem GitHub, sem `gh`, `project.ci: false`) ele mesmo roda o verify local e
|
|
45
|
+
diz por quê. **Quando a saída mostrar `CI rodando`, despache o avaliador (passo 4) sem esperar o
|
|
46
|
+
fim**: o workflow e o push já estão commitados, então a foto `--before-eval` não os acusa como
|
|
47
|
+
mutação, e a suíte corre no CI em paralelo. Saiu `verify local`: espere o fim antes do passo 4 —
|
|
48
|
+
suíte local e `mutate` disputam a máquina. Exit 2 = trabalho fora de commit; exit 3 (`pending`/`busy`)
|
|
49
|
+
não é vermelho (ver Ritmo). Rode-a só depois da última task: o `gate-check` pausa o ship se o
|
|
50
|
+
último stamp é de escopo `task:{id}`. **Sem `--filter`, sempre**: `verify {feature}` **nunca recorta**, e um verify filtrado não persiste o
|
|
43
51
|
stamp. Se o JSON vier com `repeatOf`, nada mudou desde a rodada anterior — use aquela. Esta é a
|
|
44
52
|
única execução de testes do Gate 3: o avaliador não roda a suíte de novo.
|
|
45
|
-
- Nó `e2e`: `pass` → passe a URL ao avaliador (`morph-spec e2e status {feature} --json` →
|
|
46
|
-
`baseUrl`)
|
|
47
|
-
(`
|
|
48
|
-
|
|
49
|
-
|
|
53
|
+
- Nó `e2e`: `pass` local → passe a URL ao avaliador (`morph-spec e2e status {feature} --json` →
|
|
54
|
+
`baseUrl`); `pass` no CI → a app foi exercida lá, não há stack local para navegar. `fail` →
|
|
55
|
+
correção (vermelho no CI: `gh run view <id> --log-failed`, impresso pelo verify). Vermelho por
|
|
56
|
+
config que só existe na máquina (`.env`, appsettings, connection string, secret) não é defeito do
|
|
57
|
+
código: pergunte ao usuário entre declarar o secret + `env:` no `morph-verify.yml` ou `project.ci: false`. `skip` → quem
|
|
58
|
+
classifica é o `gate-check` (`classifyE2eSkip`, em `risk-detector.js`): dispensa de projeto/escopo
|
|
59
|
+
passa; ambiente, `--skip-e2e` ou razão desconhecida pausam sozinhos.
|
|
60
|
+
- Vermelho com o avaliador ainda rodando: não mexa na árvore até ele voltar (passo 4); corrija junto
|
|
61
|
+
com os bloqueadores dele. `traceability.warnings` entram no review-report como sinal, não bloqueio.
|
|
50
62
|
|
|
51
63
|
4. **Despache o avaliador independente** (`morph-evaluator`, contexto fresco, sem Write/Edit).
|
|
52
64
|
- Tire a foto da árvore e escolha o modelo: `morph-spec report-check {feature} --before-eval --json`.
|
|
@@ -57,14 +69,14 @@ Fase review, com todas as tasks `done` e o `recap.md` em dia. Normalmente chamad
|
|
|
57
69
|
review-report. Numa worktree com grafo stale, `morph-spec graph refresh` antes.
|
|
58
70
|
```
|
|
59
71
|
dispatch Agent (subagent_type: "morph-evaluator", model: {evaluatorModel.model}) with prompt:
|
|
60
|
-
contexto: use cases + spec.md + diff da feature + JSON do verify (nós, e2e, URL)
|
|
72
|
+
contexto: use cases + spec.md + diff da feature + JSON do verify se já terminou (nós, e2e, URL)
|
|
61
73
|
+ blast radius + 1-design/mockups.md (se existir) + 3-implement/evidencias/*.md (se existir)
|
|
62
74
|
instrução: |
|
|
63
75
|
Siga .morph/framework/evals/review-checklist.md e grave
|
|
64
76
|
.morph/features/{feature}/4-review/evaluator-report.md ANTES de encerrar — o arquivo é o
|
|
65
77
|
retorno; não chame SendMessage. Se o arquivo já existir quando você começar, é resíduo de
|
|
66
78
|
outra tentativa: não o leia antes de escrever o seu (ancoragem no veredito alheio).
|
|
67
|
-
A suíte
|
|
79
|
+
A suíte roda fora de você (JSON acima, ou o CI em curso): você NÃO roda verify, build nem testes. Bash é para ler
|
|
68
80
|
(git diff/log/show, grep, morph-spec graph) e para no máximo UMA rodada de
|
|
69
81
|
`morph-spec mutate {feature}` (até 3 mutantes com `expect`), só quando o checklist pede.
|
|
70
82
|
Nada em segundo plano, nada de laço de espera. NUNCA `git checkout --`: descarta trabalho
|
|
@@ -80,8 +92,9 @@ Fase review, com todas as tasks `done` e o `recap.md` em dia. Normalmente chamad
|
|
|
80
92
|
- `tree.sinceBeforeEval.changed` vazio e `tree.markers` vazio = árvore como antes do dispatch.
|
|
81
93
|
Arquivo listado = mutação que ficou no disco: `morph-spec mutate --restore` devolve os bytes do
|
|
82
94
|
snapshot conferindo md5; fora de uma rodada de mutação, desfaça linha a linha pelo diff.
|
|
83
|
-
**NUNCA `git checkout -- src/` aqui**:
|
|
84
|
-
|
|
95
|
+
**NUNCA `git checkout -- src/` aqui**: o checkout apaga junto tudo o que não foi commitado depois
|
|
96
|
+
da prova (correção de bloqueador, trabalho de outra sessão), e no verify local a feature pode nem
|
|
97
|
+
ter commit.
|
|
85
98
|
- `tree.sinceBeforeEval` `null` = sem foto; `tree` `null` = git não respondeu, nada foi conferido.
|
|
86
99
|
- Não rode build/teste enquanto o agente está `running`.
|
|
87
100
|
|
|
@@ -91,8 +104,8 @@ Fase review, com todas as tasks `done` e o `recap.md` em dia. Normalmente chamad
|
|
|
91
104
|
MESMO avaliador por `SendMessage`, colando `tree.dirty` e `tree.commits` no recado. Só se o id não
|
|
92
105
|
retomar, despache um novo.
|
|
93
106
|
|
|
94
|
-
5. **Bloqueadores.** `**Verdict:** FIX` ou bloqueador aberto: corrija (loop da `morph-apply`), rode o
|
|
95
|
-
verify de novo e **confirme só os bloqueadores** retomando o MESMO avaliador por `SendMessage`
|
|
107
|
+
5. **Bloqueadores.** `**Verdict:** FIX` ou bloqueador aberto: corrija (loop da `morph-apply`), commite, rode o
|
|
108
|
+
`verify {feature} --ci` de novo e **confirme só os bloqueadores** retomando o MESMO avaliador por `SendMessage`
|
|
96
109
|
(com `tree.dirty`/`tree.commits` e uma foto `--before-eval` nova). Ele não reavalia a feature
|
|
97
110
|
inteira, e **nota nunca motiva nova rodada**. Avaliador encerrado: despache um novo dizendo que
|
|
98
111
|
é uma confirmação dos bloqueadores Bn — o relatório é append-only e vale o último `**Verdict:**`.
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
name: morph-stack-scan
|
|
3
3
|
description: Varre o codebase existente, detecta stack atual, compara com o stack padrão e registra desvios em stack-scan.md
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando uma feature começar em projeto brownfield (codebase já existente)
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-stack-scan
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
name: morph-standards
|
|
3
3
|
description: Localiza um standard específico via busca server-side (morph-spec standards --find) e carrega só o necessário
|
|
4
4
|
version: core
|
|
5
|
-
|
|
6
|
-
user-
|
|
7
|
-
cliVersion: "8.
|
|
5
|
+
when_to_use: Use quando precisar consultar um standard específico durante a implementação
|
|
6
|
+
user-invocable: true
|
|
7
|
+
cliVersion: "8.47.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-standards
|
|
11
11
|
|
|
12
12
|
## Objetivo
|
|
13
13
|
Encontrar o standard certo para a situação atual e carregar apenas o necessário no contexto.
|
|
14
|
-
Nunca abra o `STANDARDS.json` inteiro (
|
|
14
|
+
Nunca abra o `STANDARDS.json` inteiro (mais de 150 KB) — a busca server-side já devolve o suficiente
|
|
15
15
|
para aplicar o standard na maioria dos casos.
|
|
16
16
|
|
|
17
17
|
## Quando invocar
|
|
@@ -24,8 +24,8 @@ ou de teste — e o `spec.md` e os standards da task não bastarem para resolver
|
|
|
24
24
|
```
|
|
25
25
|
morph-spec standards --find "<domínio/tecnologia da task>" [--category <cat>] [--tags <a,b>] [--json]
|
|
26
26
|
```
|
|
27
|
-
Devolve o **top 3** como `id · path · digest` — o `digest` é
|
|
28
|
-
na maioria dos casos ele já basta para aplicar o padrão, sem abrir o `.md`.
|
|
27
|
+
Devolve o **top 3** como `id · path · digest` — o `digest` é um resumo do standard (~700 chars),
|
|
28
|
+
não o texto completo; na maioria dos casos ele já basta para aplicar o padrão, sem abrir o `.md`.
|
|
29
29
|
|
|
30
30
|
2. Se dois resultados parecerem relevantes e houver conflito, adote o mais específico ao stack
|
|
31
31
|
do projeto. Registre o conflito no `decisions.md` da feature.
|