@polymorphism-tech/morph-spec 8.34.2 → 8.35.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 +20 -3
- package/README.md +2 -2
- package/bin/morph-spec.js +18 -4
- package/bin/validate.js +379 -379
- package/claude-plugin.json +1 -1
- package/docs/CHEATSHEET.md +5 -4
- package/docs/QUICKSTART.md +1 -1
- package/framework/MORPH.md +16 -17
- package/framework/agents.json +197 -44
- package/framework/ai-pin.json +22 -0
- package/framework/commands/morph-media.md +45 -0
- package/framework/docs/CLI.md +234 -9
- package/framework/evals/proof-rubrics/README.md +76 -0
- package/framework/evals/proof-rubrics/eval-de-modelo.md +64 -0
- package/framework/evals/proof-rubrics/fiacao.md +54 -0
- package/framework/evals/proof-rubrics/guard-cego.md +52 -0
- package/framework/evals/proof-rubrics/media-claims.md +109 -0
- package/framework/evals/proof-rubrics/mutation-proof.md +77 -0
- package/framework/evals/proof-rubrics/observabilidade-genai.md +119 -0
- package/framework/evals/proof-rubrics/verde-nao-e-coberto.md +48 -0
- package/framework/evals/rubrics/architecture.md +30 -0
- package/framework/evals/rubrics/code-quality.md +26 -0
- package/framework/evals/rubrics/test-coverage.md +20 -0
- package/framework/hooks/claude-code/core/protect-spec-files.js +41 -4
- package/framework/hooks/claude-code/statusline.sh +11 -11
- package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
- package/framework/hooks/git/pre-commit/agents.sh +25 -25
- package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
- package/framework/hooks/git/pre-commit/specs.sh +50 -50
- package/framework/hooks/git/pre-push/run-tests.sh +44 -44
- package/framework/hooks/shared/e2e-check.js +135 -22
- package/framework/hooks/shared/stdin-reader.js +26 -26
- package/framework/rules/ai-agents-standards.md +14 -2
- package/framework/schemas/ai-pin.schema.json +97 -0
- package/framework/schemas/config.schema.json +107 -0
- package/framework/schemas/feature.schema.json +23 -4
- package/framework/skills/core/create-umbraco-lp/SKILL.md +1 -1
- package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +1 -1
- package/framework/skills/core/morph-apply/SKILL.md +26 -5
- package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
- package/framework/skills/core/morph-eval/SKILL.md +1 -1
- package/framework/skills/core/morph-hotfix/SKILL.md +2 -2
- package/framework/skills/core/morph-implement/SKILL.md +18 -2
- package/framework/skills/core/morph-media/SKILL.md +215 -0
- package/framework/skills/core/morph-plan/SKILL.md +33 -2
- package/framework/skills/core/morph-proposal/SKILL.md +1 -1
- package/framework/skills/core/morph-review/SKILL.md +166 -9
- package/framework/skills/core/morph-stack-scan/SKILL.md +1 -1
- package/framework/skills/core/morph-standards/SKILL.md +1 -1
- package/framework/skills/core/morph-uiux/SKILL.md +1 -1
- package/framework/standards/PROVENANCE.json +81 -3
- package/framework/standards/STANDARDS.json +1483 -839
- package/framework/standards/ai-agents/agent-archetypes.md +160 -0
- package/framework/standards/ai-agents/agent-session.md +164 -68
- package/framework/standards/ai-agents/agent-spec.md +196 -0
- package/framework/standards/ai-agents/batching.md +61 -37
- package/framework/standards/ai-agents/context-providers.md +97 -24
- package/framework/standards/ai-agents/conversational-agent-with-phases.md +239 -0
- package/framework/standards/ai-agents/cost-and-budget.md +256 -0
- package/framework/standards/ai-agents/durable-workflows-hitl.md +98 -5
- package/framework/standards/ai-agents/evals-with-cache.md +289 -0
- package/framework/standards/ai-agents/guardrails.md +222 -0
- package/framework/standards/ai-agents/llm-runtime-defaults.md +226 -0
- package/framework/standards/ai-agents/mcp-server.md +119 -18
- package/framework/standards/ai-agents/mcp-tools.md +85 -32
- package/framework/standards/ai-agents/media-pipeline.md +352 -0
- package/framework/standards/ai-agents/media-video.md +267 -0
- package/framework/standards/ai-agents/middleware-patterns.md +39 -5
- package/framework/standards/ai-agents/modalities-image-gen.md +354 -105
- package/framework/standards/ai-agents/modalities-speech-to-text.md +8 -2
- package/framework/standards/ai-agents/modalities-text-to-speech.md +10 -2
- package/framework/standards/ai-agents/modalities-vision.md +6 -2
- package/framework/standards/ai-agents/multi-agent-patterns.md +61 -5
- package/framework/standards/ai-agents/observability-patterns.md +227 -17
- package/framework/standards/ai-agents/production.md +38 -9
- package/framework/standards/ai-agents/prompt-sources.md +389 -0
- package/framework/standards/ai-agents/providers/model-registry.md +174 -39
- package/framework/standards/ai-agents/rag-custom-pgvector.md +69 -4
- package/framework/standards/ai-agents/service-tier-flex.md +27 -19
- package/framework/standards/ai-agents/setup.md +166 -50
- package/framework/standards/ai-agents/structured-output.md +34 -3
- package/framework/standards/ai-agents/sweet-spot.md +23 -3
- package/framework/standards/ai-agents/testing-ai.md +236 -0
- package/framework/standards/ai-agents/vector-data-extensions.md +50 -20
- package/framework/standards/ai-agents/workflows.md +27 -7
- package/framework/standards/frontend/design-system/ai-image-generation.md +12 -0
- package/framework/standards/frontend/design-system/ai-video-generation.md +13 -0
- package/framework/standards/infrastructure/docker/local-compose-isolation.md +3 -1
- package/framework/templates/.idea/morph-templates.xml +92 -0
- package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
- package/framework/templates/IDE-SNIPPETS.md +262 -262
- package/framework/templates/REGISTRY.json +13 -0
- package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
- package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
- package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
- package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
- package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +1 -1
- package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
- package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
- package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
- package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
- package/framework/templates/code/dotnet/database/migration.cs +83 -83
- package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
- package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
- package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
- package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +1 -1
- package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
- package/framework/templates/code/typescript/contracts.ts +167 -167
- package/framework/templates/docs/clarifications.md +253 -253
- package/framework/templates/docs/schema-analysis.md +119 -119
- package/framework/templates/docs/ui-components.md +52 -52
- package/framework/templates/docs/ui-design-system.md +76 -76
- package/framework/templates/docs/ui-flows.md +167 -167
- package/framework/templates/docs/ui-mockups.md +98 -98
- package/framework/templates/dotnet/ai-kit/Directory.Build.props +25 -0
- package/framework/templates/dotnet/ai-kit/Directory.Packages.props +26 -0
- package/framework/templates/dotnet/ai-kit/Morph.AiKit.sln +56 -0
- package/framework/templates/dotnet/ai-kit/NuGet.config +12 -0
- package/framework/templates/dotnet/ai-kit/README.md +128 -0
- package/framework/templates/dotnet/ai-kit/global.json +9 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentApi.cs +65 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactory.cs +289 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentFactoryOptions.cs +91 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpec.cs +91 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Agents/AgentSpecOptions.cs +181 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/AiKitAssemblyMarker.cs +14 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/ConversationStore.cs +174 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/IConversationStore.cs +54 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Conversation/InMemoryConversationStore.cs +75 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/CountingChatClient.cs +71 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalAssertion.cs +246 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheMissException.cs +57 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheOptions.cs +78 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalCacheStamp.cs +225 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalFixture.cs +463 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalMode.cs +32 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalQualityEvaluators.cs +49 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalScenario.cs +214 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/EvalSummary.cs +168 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/OfflineChatClient.cs +142 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Evals/ShortPathResponseCache.cs +349 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaGenerator.cs +42 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/IMediaProvider.cs +77 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaArtifact.cs +28 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaDisclosure.cs +107 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaGenerator.cs +253 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaIdempotencyKey.cs +103 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJob.cs +259 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobId.cs +21 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaJobState.cs +47 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaPricing.cs +102 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaProvenance.cs +44 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaRequest.cs +192 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaResult.cs +94 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaReview.cs +99 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaSeams.cs +97 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MediaStore.cs +133 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/MorphMedia.cs +93 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/GoogleImageProvider.cs +112 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/OpenAIImageProvider.cs +288 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Media/Providers/VeoVideoProvider.cs +158 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/IUsageCostSink.cs +29 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostMiddleware.cs +208 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Middleware/UsageCostRecord.cs +95 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Morph.AiKit.csproj +38 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphOpenTelemetryExtensions.cs +119 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Observability/MorphTelemetryOptions.cs +82 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/IProviderClientFactory.cs +33 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelAlias.cs +267 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/ModelRegistry.cs +474 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Providers/model-registry.v2.json +87 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaIngest.cs +169 -0
- package/framework/templates/dotnet/ai-kit/src/Morph.AiKit/Rag/DeltaPlan.cs +49 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentFactoryTests.cs +495 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/AgentSpecTests.cs +260 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ConversationStoreTests.cs +405 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/DeltaIngestTests.cs +379 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalAssertionTests.cs +197 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheMissTests.cs +139 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalCacheStampTests.cs +157 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFailuresTests.cs +178 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalFixtureTests.cs +153 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalRefreshTests.cs +194 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/EvalWorkspace.cs +86 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/KitEvals.cs +213 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Evals/OfflineChatClientTests.cs +95 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClient.cs +225 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeChatClientTests.cs +215 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeClock.cs +33 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeMediaProvider.cs +89 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeProviderClientFactory.cs +55 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/FakeUsageCostSink.cs +60 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Fakes/InMemoryMediaStore.cs +131 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAccessibilityTests.cs +133 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaAliasIsNotAnAgentTests.cs +127 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaDisclosureTests.cs +216 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaGeneratorTests.cs +264 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaIdempotencyKeyTests.cs +148 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaJobStateTests.cs +184 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaReviewTests.cs +89 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/MediaStoreTests.cs +98 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/ModelRegistryTests.cs +451 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/Morph.AiKit.Tests.csproj +76 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/SkeletonSmokeTests.cs +33 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/TelemetryTests.cs +261 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/UsageCostMiddlewareTests.cs +374 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/.morph-eval-cache.json +12 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/orcamento.acme.a-resposta-estruturada/1/CF70A7CE27BBD66A/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.a-saudacao/1/19F631228C6E00BA/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.acme.b-escalonamento/1/A24A7C9BDD8239D8/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/contents.data +13 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-cache/cache/triagem.globex.a-saudacao/1/E38CD37DF003EDB7/entry.json +7 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/orcamento/acme/a-resposta-estruturada.json +24 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/a-saudacao.json +23 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/acme/b-escalonamento.json +24 -0
- package/framework/templates/dotnet/ai-kit/tests/Morph.AiKit.Tests/eval-datasets/triagem/globex/a-saudacao.json +23 -0
- package/framework/templates/feature/decisions.md +122 -122
- package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
- package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
- package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
- package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
- package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
- package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
- package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
- package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
- package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
- package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
- package/framework/templates/infrastructure/github/README.md +56 -56
- package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
- package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
- package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
- package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
- package/framework/templates/integrations/asaas-client.cs +387 -387
- package/framework/templates/integrations/asaas-webhook.cs +351 -351
- package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
- package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
- package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
- package/framework/templates/project/validate.js +120 -120
- package/framework/templates/state.template.json +17 -17
- package/framework/templates/ui/design-system.css +226 -226
- package/package.json +3 -3
- package/src/commands/dashboard/dashboard.js +53 -53
- package/src/commands/e2e/e2e.js +15 -2
- package/src/commands/index.js +13 -13
- package/src/commands/project/checkpoint.js +209 -209
- package/src/commands/project/doctor.js +140 -5
- package/src/commands/project/update.js +469 -153
- package/src/commands/project/worktree.js +8 -1
- package/src/commands/state/advance.js +24 -2
- package/src/commands/state/approve.js +33 -1
- package/src/commands/state/create.js +72 -11
- package/src/commands/state/finish.js +333 -21
- package/src/commands/state/gate-check.js +190 -6
- package/src/commands/state/score.js +36 -1
- package/src/commands/validation/verify.js +134 -25
- package/src/core/state/phase-state-machine.js +197 -197
- package/src/core/state/state-manager.js +9 -1
- package/src/core/templates/template-renderer.js +477 -477
- package/src/dashboard/app/components/DetailPanel.jsx +11 -11
- package/src/dashboard/app/components/FlowGraph.jsx +17 -17
- package/src/dashboard/app/components/SearchFilter.jsx +22 -22
- package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
- package/src/dashboard/app/main.jsx +13 -13
- package/src/dashboard/app/pages/AgentMap.jsx +370 -370
- package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
- package/src/dashboard/app/pages/RulesMap.jsx +273 -273
- package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
- package/src/dashboard/app/pages/Standards.jsx +332 -332
- package/src/dashboard/app/styles/index.css +47 -47
- package/src/dashboard/index.html +12 -12
- package/src/dashboard/package.json +24 -24
- package/src/dashboard/scanner/phases-scanner.js +15 -15
- package/src/dashboard/scanner/rubrics-scanner.js +12 -12
- package/src/dashboard/scanner/rules-scanner.js +37 -37
- package/src/dashboard/scanner/skills-scanner.js +43 -43
- package/src/dashboard/scanner/squads-scanner.js +13 -13
- package/src/dashboard/vite-plugin-morph-data.js +17 -17
- package/src/dashboard/vite.config.js +24 -24
- package/src/lib/ai/ai-checks.js +182 -0
- package/src/lib/ai/ai-project-scan.js +347 -0
- package/src/lib/ai/code-audit.js +181 -0
- package/src/lib/ai/comment-stripper.js +184 -0
- package/src/lib/ai/pin-drift.js +138 -0
- package/src/lib/ai/registry-audit.js +285 -0
- package/src/lib/detectors/design-system-detector.js +188 -188
- package/src/lib/detectors/index.js +217 -217
- package/src/lib/e2e/compose-env.js +50 -4
- package/src/lib/evaluator-report.js +269 -15
- package/src/lib/generators/design-system-generator.js +508 -508
- package/src/lib/generators/settings-generator.js +209 -209
- package/src/lib/git/default-branch.js +92 -4
- package/src/lib/hooks/hook-executor.js +167 -167
- package/src/lib/installers/effects.js +193 -0
- package/src/lib/installers/mcp-installer.js +719 -719
- package/src/lib/installers/templates-reconcile.js +3 -3
- package/src/lib/risk-detector.js +284 -0
- package/src/lib/standards/verified-against.js +276 -0
- package/src/lib/tasks/eval-node.js +485 -0
- package/src/lib/tasks/linux-runner.js +297 -0
- package/src/lib/tasks/task-classifier.js +30 -30
- package/src/lib/tasks/task-parser.js +209 -209
- package/src/lib/tasks/test-nodes.js +486 -0
- package/src/lib/tasks/test-runner.js +410 -33
- package/src/lib/validators/checkpoint-persistence.js +39 -39
- package/src/lib/validators/css/css-validator.js +340 -340
- package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
- package/src/lib/validators/shared/issue-counter.js +14 -14
- package/src/lib/validators/verify-runner.js +583 -28
- package/src/lib/worktree/docker-audit.js +287 -0
- package/src/lib/worktree/env-allocator.js +24 -0
- package/src/lib/worktree/worktree-audit.js +30 -1
- package/src/scripts/setup-infra.js +24 -11
- package/src/utils/agent-id-mapper.js +11 -11
- package/src/utils/agents-installer.js +18 -8
- package/src/utils/claude-md-injector.js +10 -5
- package/src/utils/claude-settings-manager.js +300 -300
- package/src/utils/file-copier.js +11 -4
- package/src/utils/hooks-installer.js +29 -26
- package/src/utils/skills-installer.js +36 -29
- package/src/utils/version-checker.js +68 -3
- package/framework/standards/ai-agents/prompts-in-db.md +0 -214
|
@@ -1,26 +1,26 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Shared stdin reader for Claude Code hooks.
|
|
3
|
-
*
|
|
4
|
-
* Reads JSON payload from stdin (provided by Claude Code to hooks).
|
|
5
|
-
* Returns parsed object or null on failure.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Read and parse JSON from stdin
|
|
10
|
-
* @returns {Promise<Object|null>} Parsed JSON or null
|
|
11
|
-
*/
|
|
12
|
-
export function readStdin() {
|
|
13
|
-
return new Promise((resolve) => {
|
|
14
|
-
let input = '';
|
|
15
|
-
process.stdin.setEncoding('utf-8');
|
|
16
|
-
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
17
|
-
process.stdin.on('end', () => {
|
|
18
|
-
try {
|
|
19
|
-
resolve(JSON.parse(input || '{}'));
|
|
20
|
-
} catch {
|
|
21
|
-
resolve(null);
|
|
22
|
-
}
|
|
23
|
-
});
|
|
24
|
-
process.stdin.on('error', () => resolve(null));
|
|
25
|
-
});
|
|
26
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Shared stdin reader for Claude Code hooks.
|
|
3
|
+
*
|
|
4
|
+
* Reads JSON payload from stdin (provided by Claude Code to hooks).
|
|
5
|
+
* Returns parsed object or null on failure.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Read and parse JSON from stdin
|
|
10
|
+
* @returns {Promise<Object|null>} Parsed JSON or null
|
|
11
|
+
*/
|
|
12
|
+
export function readStdin() {
|
|
13
|
+
return new Promise((resolve) => {
|
|
14
|
+
let input = '';
|
|
15
|
+
process.stdin.setEncoding('utf-8');
|
|
16
|
+
process.stdin.on('data', (chunk) => { input += chunk; });
|
|
17
|
+
process.stdin.on('end', () => {
|
|
18
|
+
try {
|
|
19
|
+
resolve(JSON.parse(input || '{}'));
|
|
20
|
+
} catch {
|
|
21
|
+
resolve(null);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
process.stdin.on('error', () => resolve(null));
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -17,7 +17,7 @@ stacks:
|
|
|
17
17
|
@.morph/framework/standards/ai-agents/providers/model-registry.md
|
|
18
18
|
@.morph/framework/standards/ai-agents/structured-output.md
|
|
19
19
|
@.morph/framework/standards/ai-agents/multi-agent-patterns.md
|
|
20
|
-
@.morph/framework/standards/ai-agents/
|
|
20
|
+
@.morph/framework/standards/ai-agents/prompt-sources.md
|
|
21
21
|
@.morph/framework/standards/ai-agents/rag-custom-pgvector.md
|
|
22
22
|
@.morph/framework/standards/ai-agents/middleware-patterns.md
|
|
23
23
|
@.morph/framework/standards/ai-agents/observability-patterns.md
|
|
@@ -34,7 +34,9 @@ stacks:
|
|
|
34
34
|
| Standard | Carregue quando a feature envolve |
|
|
35
35
|
|----------|-----------------------------------|
|
|
36
36
|
| `ai-agents/modalities-vision.md` | imagem → texto (OCR, análise de documento, visão) |
|
|
37
|
-
| `ai-agents/modalities-image-gen.md` |
|
|
37
|
+
| `ai-agents/modalities-image-gen.md` | gerar/editar imagem em runtime: catálogo, marketing, variação de produto — aliases pinados, custo por chamada, deprecações |
|
|
38
|
+
| `ai-agents/media-video.md` | gerar vídeo em runtime: Veo via `Google.GenAI`, provedores só-HTTP, custo por segundo, o arquivo que expira |
|
|
39
|
+
| `ai-agents/media-pipeline.md` | **qualquer** feature que gere mídia: a regra dura (nunca no turno de conversa), estados, revisão humana, proveniência, marcação (AI Act art. 50) |
|
|
38
40
|
| `ai-agents/modalities-speech-to-text.md` | áudio → texto (transcrição, legendagem) |
|
|
39
41
|
| `ai-agents/modalities-text-to-speech.md` | texto → áudio (síntese de voz) |
|
|
40
42
|
| `ai-agents/batching.md` | processar N prompts independentes em lote (Batch API) |
|
|
@@ -43,4 +45,14 @@ stacks:
|
|
|
43
45
|
| `ai-agents/context-providers.md` | injeção dinâmica de contexto (`AIContextProvider`) |
|
|
44
46
|
| `ai-agents/mcp-tools.md` | agente MAF consome um MCP server externo |
|
|
45
47
|
| `ai-agents/mcp-server.md` | projeto expõe capacidades como MCP server |
|
|
48
|
+
| `ai-agents/agent-archetypes.md` | escolher a FORMA do agente na fase de plano (conversa com fases, one-shot em lote, visão + structured output) |
|
|
49
|
+
| `ai-agents/agent-spec.md` | o agente como DADO — um `AgentSpec` imutável por agente, catálogo e defaults |
|
|
50
|
+
| `ai-agents/conversational-agent-with-phases.md` | conversa com fases no turno — allow-list de tools, `ChatToolMode`, teto de tool calls |
|
|
51
|
+
| `ai-agents/guardrails.md` | regra proibida vira código — guard de tool, pertinência, argumento não confiável, fail-open |
|
|
52
|
+
| `ai-agents/testing-ai.md` | testar agente sem rede — `IChatClient` fake, harness de turno, golden de prompt |
|
|
53
|
+
| `ai-agents/evals-with-cache.md` | eval de modelo/prompt no CI **sem credencial e sem rede**: cache de respostas commitada, dataset versionado, o que entra na chave de cache, troca de modelo e regressão de prompt |
|
|
54
|
+
| `ai-agents/cost-and-budget.md` | custo em dinheiro — `UsageCostMiddleware`, tarifa por token, teto de orçamento |
|
|
55
|
+
| `ai-agents/llm-runtime-defaults.md` | knobs de runtime da chamada — timeout, retry, `strict` JSON schema, temperatura/reasoning |
|
|
56
|
+
| `ai-agents/durable-workflows-hitl.md` | workflow durável e human-in-the-loop — checkpoint, `RequestPort`, aprovação de tool |
|
|
57
|
+
| `ai-agents/vector-data-extensions.md` | abstração `Microsoft.Extensions.VectorData` e conectores (pgvector, ingestão) |
|
|
46
58
|
| `integration/mcp/mcp-tools.md` | integração MCP cross-domain (fora do escopo MAF) |
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"$id": "https://polymorphism.com.br/morph-spec/schemas/ai-pin.schema.json",
|
|
4
|
+
"title": "morph-spec AI package pin",
|
|
5
|
+
"description": "Shape of framework/ai-pin.json — the single source of truth for the AI package versions the framework commits to. Written by a human after checking api.nuget.org; read by scripts/generate-ai-pin-props.js (Central Package Management + global.json) and by src/lib/standards/verified-against.js (age of ai-agents standards against pinnedAt). Every version is exact SemVer: a range here would restore floating versions in the generated .props, which is the defect this file exists to remove.",
|
|
6
|
+
"type": "object",
|
|
7
|
+
"required": ["pinnedAt", "source", "targetFramework", "sdk", "packages", "toolchain"],
|
|
8
|
+
"additionalProperties": false,
|
|
9
|
+
"properties": {
|
|
10
|
+
"$schema": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"description": "Relative path to this schema, so an editor validates the pin while it is edited."
|
|
13
|
+
},
|
|
14
|
+
"pinnedAt": {
|
|
15
|
+
"type": "string",
|
|
16
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
|
|
17
|
+
"description": "ISO date on which a human checked these versions against the registry. It is the anchor of the ai-agents freshness window — NOT derived from `published`: `published` is a registry fact, `pinnedAt` is the framework's commitment. A date in the future is a pin error, never a fresh standard."
|
|
18
|
+
},
|
|
19
|
+
"source": {
|
|
20
|
+
"type": "string",
|
|
21
|
+
"pattern": "^https://",
|
|
22
|
+
"description": "The registry endpoint the versions were read from, so the check is reproducible."
|
|
23
|
+
},
|
|
24
|
+
"targetFramework": {
|
|
25
|
+
"type": "string",
|
|
26
|
+
"pattern": "^net\\d+\\.\\d+$",
|
|
27
|
+
"description": "TFM the kit compiles against — the TFM the pinned Microsoft.Agents.AI declares."
|
|
28
|
+
},
|
|
29
|
+
"sdk": {
|
|
30
|
+
"type": "string",
|
|
31
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
32
|
+
"description": "SDK band written into the kit's global.json and read by actions/setup-dotnet."
|
|
33
|
+
},
|
|
34
|
+
"packages": {
|
|
35
|
+
"type": "object",
|
|
36
|
+
"description": "The AI packages the framework commits to. The SET is closed HERE, by `required` plus `maxProperties` — issue #92 pinned five, and issue #97 added the three Evaluation packages that make `verify` able to run evals from a committed response cache. `patternProperties` still carries the per-entry SHAPE, because JSON Schema cannot name a closed set of keys and repeat their shape without writing it once per key; test/framework/ai-pin.test.js reads THIS `required` list rather than a literal of its own, so the pin and its ruler can never name different sets.",
|
|
37
|
+
"required": [
|
|
38
|
+
"Microsoft.Agents.AI",
|
|
39
|
+
"Microsoft.Extensions.AI",
|
|
40
|
+
"OpenAI",
|
|
41
|
+
"Google.GenAI",
|
|
42
|
+
"ModelContextProtocol",
|
|
43
|
+
"Microsoft.Extensions.AI.Evaluation",
|
|
44
|
+
"Microsoft.Extensions.AI.Evaluation.Quality",
|
|
45
|
+
"Microsoft.Extensions.AI.Evaluation.Reporting"
|
|
46
|
+
],
|
|
47
|
+
"minProperties": 8,
|
|
48
|
+
"maxProperties": 8,
|
|
49
|
+
"additionalProperties": false,
|
|
50
|
+
"patternProperties": {
|
|
51
|
+
"^[A-Za-z0-9_.-]+$": {
|
|
52
|
+
"type": "object",
|
|
53
|
+
"required": ["version", "published", "role"],
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"properties": {
|
|
56
|
+
"version": {
|
|
57
|
+
"type": "string",
|
|
58
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
59
|
+
"description": "Exact SemVer. No range, no wildcard, no floating version."
|
|
60
|
+
},
|
|
61
|
+
"published": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
|
|
64
|
+
"description": "ISO publication date of that exact version in the registry."
|
|
65
|
+
},
|
|
66
|
+
"role": {
|
|
67
|
+
"type": "string",
|
|
68
|
+
"pattern": "^[a-z0-9-]+$",
|
|
69
|
+
"description": "Human-readable label (maf-core, provider, mcp, ...). Documentation, not code semantics."
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
"toolchain": {
|
|
76
|
+
"type": "object",
|
|
77
|
+
"description": "Build/test packages. They live in the SAME file because the generator writes a single Directory.Packages.props; splitting them would produce two version files and the very second-truth problem the pin removes.",
|
|
78
|
+
"minProperties": 3,
|
|
79
|
+
"maxProperties": 3,
|
|
80
|
+
"additionalProperties": false,
|
|
81
|
+
"patternProperties": {
|
|
82
|
+
"^[A-Za-z0-9_.-]+$": {
|
|
83
|
+
"type": "object",
|
|
84
|
+
"required": ["version"],
|
|
85
|
+
"additionalProperties": false,
|
|
86
|
+
"properties": {
|
|
87
|
+
"version": {
|
|
88
|
+
"type": "string",
|
|
89
|
+
"pattern": "^\\d+\\.\\d+\\.\\d+$",
|
|
90
|
+
"description": "Exact SemVer, same rule as `packages`."
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
3
|
+
"title": "MORPH-SPEC .morph/config/config.json",
|
|
4
|
+
"description": "Describes ONLY project.tests[] — the plural declaration of the project's test suites. Everything else in config.json is deliberately left open (additionalProperties: true) so that configs already in the field never break on a key this schema has not heard of. The authority at runtime is validateTestNodes() in src/lib/tasks/test-nodes.js: a schema nothing calls is decoration.",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": true,
|
|
7
|
+
"properties": {
|
|
8
|
+
"project": {
|
|
9
|
+
"type": "object",
|
|
10
|
+
"additionalProperties": true,
|
|
11
|
+
"properties": {
|
|
12
|
+
"tests": {
|
|
13
|
+
"type": "array",
|
|
14
|
+
"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'.",
|
|
15
|
+
"items": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"additionalProperties": false,
|
|
18
|
+
"required": ["id", "command"],
|
|
19
|
+
"properties": {
|
|
20
|
+
"id": {
|
|
21
|
+
"type": "string",
|
|
22
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$",
|
|
23
|
+
"description": "Unique within the array. What `verify --filter` matches and the key of nodes.tests.runs[]. A duplicate id is a config error, not a silent tie."
|
|
24
|
+
},
|
|
25
|
+
"command": {
|
|
26
|
+
"type": "string",
|
|
27
|
+
"minLength": 1,
|
|
28
|
+
"description": "Literal command, executed by the shell from `cwd`."
|
|
29
|
+
},
|
|
30
|
+
"cwd": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"minLength": 1,
|
|
33
|
+
"default": ".",
|
|
34
|
+
"description": "Relative to the project root. A path that resolves outside the root is refused: it addresses another tree."
|
|
35
|
+
},
|
|
36
|
+
"runner": {
|
|
37
|
+
"type": "string",
|
|
38
|
+
"enum": ["dotnet", "vitest", "jest", "node-test", "playwright", "none", "evals"],
|
|
39
|
+
"description": "Chooses the test-count extractor and whether a prebuild applies. Inferred from `command` when omitted; `none` means the count is UNKNOWN, never zero. `evals` is the ONLY value that is never inferred - it is a declaration that this suite reads a committed response cache, and it REQUIRES the `evals` block below."
|
|
40
|
+
},
|
|
41
|
+
"expectedCount": {
|
|
42
|
+
"type": "integer",
|
|
43
|
+
"minimum": 0,
|
|
44
|
+
"description": "Recorded baseline. Written ONLY by `morph-spec verify --record-baseline`, from a green run — never typed by hand."
|
|
45
|
+
},
|
|
46
|
+
"timeoutMs": {
|
|
47
|
+
"type": "integer",
|
|
48
|
+
"minimum": 1,
|
|
49
|
+
"description": "Ceiling for this node. Exists because the derived default (120s x chained projects) is shaped for `dotnet test` and is hostile to a Node suite that takes twelve minutes."
|
|
50
|
+
},
|
|
51
|
+
"build": {
|
|
52
|
+
"type": "array",
|
|
53
|
+
"items": { "type": "string", "minLength": 1 },
|
|
54
|
+
"description": "Test projects to compile before running (runner 'dotnet' only). Without it, `--no-build` in the command has no fresh binary behind it."
|
|
55
|
+
},
|
|
56
|
+
"e2e": {
|
|
57
|
+
"type": "boolean",
|
|
58
|
+
"default": false,
|
|
59
|
+
"description": "Requires the application stack to be up. Runs at feature scope only, never in the per-task loop."
|
|
60
|
+
},
|
|
61
|
+
"linuxImage": {
|
|
62
|
+
"type": "string",
|
|
63
|
+
"minLength": 1,
|
|
64
|
+
"description": "Overrides the container image used by `verify --linux` for this node."
|
|
65
|
+
},
|
|
66
|
+
"evals": {
|
|
67
|
+
"type": "object",
|
|
68
|
+
"additionalProperties": false,
|
|
69
|
+
"required": ["cachePath"],
|
|
70
|
+
"description": "Required by, and only valid for, runner evals. Declared on any other runner it would be a key the verifier silently ignores - the same fail-open shape as a typo in tests[].",
|
|
71
|
+
"properties": {
|
|
72
|
+
"cachePath": {
|
|
73
|
+
"type": "string",
|
|
74
|
+
"minLength": 1,
|
|
75
|
+
"description": "Root of the response-cache tree, relative to the project root, and COMMITTED. A path that resolves outside the root is refused, same rule as `cwd`. No default: a silent one would create a cache tree somewhere nobody declared."
|
|
76
|
+
},
|
|
77
|
+
"datasetPath": {
|
|
78
|
+
"type": "string",
|
|
79
|
+
"minLength": 1,
|
|
80
|
+
"description": "Root of the versioned dataset, laid out as {agent}/{tenant}/{scenario}.json. Defaults to `eval-datasets` beside cachePath."
|
|
81
|
+
},
|
|
82
|
+
"envFile": {
|
|
83
|
+
"type": "string",
|
|
84
|
+
"minLength": 1,
|
|
85
|
+
"description": "GITIGNORED file holding the provider credential, read ONLY by --refresh-cache. Same pattern as e2e.auth.envFile; a credential never travels in the committed config. Defaults to `.env.evals`."
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"evals": {
|
|
93
|
+
"type": "object",
|
|
94
|
+
"additionalProperties": true,
|
|
95
|
+
"description": "Project-level eval settings, distinct from the per-node block above: this one describes the PROJECT (which paths count as prompt or model), not one suite.",
|
|
96
|
+
"properties": {
|
|
97
|
+
"watch": {
|
|
98
|
+
"type": "array",
|
|
99
|
+
"items": { "type": "string", "minLength": 1 },
|
|
100
|
+
"description": "Globs that mean 'this is a prompt or a model'. Matched against what the feature changed (git diff plus untracked) to decide whether Gate 3 should pause for a missing eval. Absent means the project declares no such paths - reported as a reason of its own, distinct from 'declared and nothing was touched'."
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -107,7 +107,8 @@
|
|
|
107
107
|
"build": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
108
108
|
"tests": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
109
109
|
"validators": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
110
|
-
"e2e": { "type": "string", "enum": ["pass", "fail", "skip"], "description": "Docker bring-up + Playwright specs against the running stack. Absent on entries written before the node existed — which is why it is NOT in `required`." }
|
|
110
|
+
"e2e": { "type": "string", "enum": ["pass", "fail", "skip"], "description": "Docker bring-up + Playwright specs against the running stack. Absent on entries written before the node existed — which is why it is NOT in `required`." },
|
|
111
|
+
"evals": { "type": ["string", "null"], "enum": ["pass", "fail", "skip", null], "description": "Eval suites, pulled out of the tests rollup. Written by the SAME function that writes the singular stamp (nodeStatuses in verify.js): the two shapes must stay identical, or a stamp would omit what the history records. null means the project declares no eval node at all — distinct from skip, which means it declares one and this run did not execute it. Absent on entries written before the field existed, which is why it is NOT in required." }
|
|
111
112
|
},
|
|
112
113
|
"additionalProperties": false
|
|
113
114
|
},
|
|
@@ -134,7 +135,8 @@
|
|
|
134
135
|
"build": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
135
136
|
"tests": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
136
137
|
"validators": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
137
|
-
"e2e": { "type": "string", "enum": ["pass", "fail", "skip"], "description": "Docker bring-up + Playwright specs against the running stack. Absent on entries written before the node existed — which is why it is NOT in `required`." }
|
|
138
|
+
"e2e": { "type": "string", "enum": ["pass", "fail", "skip"], "description": "Docker bring-up + Playwright specs against the running stack. Absent on entries written before the node existed — which is why it is NOT in `required`." },
|
|
139
|
+
"evals": { "type": ["string", "null"], "enum": ["pass", "fail", "skip", null], "description": "Eval suites, pulled out of the tests rollup. Written by the SAME function that writes the singular stamp (nodeStatuses in verify.js): the two shapes must stay identical, or a stamp would omit what the history records. null means the project declares no eval node at all — distinct from skip, which means it declares one and this run did not execute it. Absent on entries written before the field existed, which is why it is NOT in required." }
|
|
138
140
|
},
|
|
139
141
|
"additionalProperties": false
|
|
140
142
|
},
|
|
@@ -149,13 +151,30 @@
|
|
|
149
151
|
},
|
|
150
152
|
"verification": {
|
|
151
153
|
"type": "object",
|
|
152
|
-
"description": "The single latest deterministic verify stamp (any scope), written ONLY by `morph-spec verify`. Distinct from `verifications`/`taskVerifications` above (per-scope history with attempts/nodes): this is overwritten by every verify call regardless of scope, carrying just enough to correlate a pass/fail with the exact commit it covers. Primary consumer: `morph-spec gate-check`, which feeds `status` to shouldPauseGate as `verificationStatus` — a red verify pauses the gate (risk-detector.js).
|
|
154
|
+
"description": "The single latest deterministic verify stamp (any scope), written ONLY by `morph-spec verify`. Distinct from `verifications`/`taskVerifications` above (per-scope history with attempts/nodes): this is overwritten by every verify call regardless of scope, carrying just enough to correlate a pass/fail with the exact commit it covers. Primary consumer: `morph-spec gate-check`, which feeds `status` to shouldPauseGate as `verificationStatus` — a red verify pauses the gate (risk-detector.js) — and `nodes.e2e`/`e2eReason` as `e2eStatus`/`e2eReason`, the pair that decides whether an e2e SKIP is a recorded dispensation or an absence of proof (a skip never reddens `status`, so the rollup alone is blind to it). `scope` is the third pause input: a dispensation only counts from a feature-scoped stamp (see the field below). The rest (sha/ts, and the derived `verificationStale`) is audit context.",
|
|
153
155
|
"required": ["status", "sha", "ts", "scope"],
|
|
154
156
|
"properties": {
|
|
155
157
|
"status": { "type": "string", "enum": ["pass", "fail"] },
|
|
158
|
+
"nodes": {
|
|
159
|
+
"type": "object",
|
|
160
|
+
"description": "Per-node status of the verify that wrote this stamp. NOT in `required`: stamps written before the field existed carry only the rollup. Same values as `verifications.feature.nodes`, repeated here because gate-check reads the stamp and nothing else.",
|
|
161
|
+
"properties": {
|
|
162
|
+
"build": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
163
|
+
"tests": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
164
|
+
"validators": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
165
|
+
"e2e": { "type": "string", "enum": ["pass", "fail", "skip"] },
|
|
166
|
+
"evals": {
|
|
167
|
+
"type": ["string", "null"],
|
|
168
|
+
"enum": ["pass", "fail", "skip", null],
|
|
169
|
+
"description": "Status of the `runner: \"evals\"` entries of nodes.tests.runs[], pulled out of the rollup. The rollup cannot answer what Gate 3 asks: a red eval and a red unit test both read as tests:fail, and an eval SKIPPED at task scope leaves the rollup green. null means this project declares NO eval node - distinct from 'skip', which means it declares one and this run did not execute it; risk-detector.js pauses on the two for different reasons because they call for different actions. Absent on stamps written before this field existed."
|
|
170
|
+
}
|
|
171
|
+
},
|
|
172
|
+
"additionalProperties": false
|
|
173
|
+
},
|
|
174
|
+
"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." },
|
|
156
175
|
"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." },
|
|
157
176
|
"ts": { "type": "string", "format": "date-time", "description": "Server-side timestamp, same instant as the corresponding verifications/taskVerifications entry's updatedAt." },
|
|
158
|
-
"scope": { "type": "string", "description": "'feature', or 'task:<id>' for a task-scoped verify." }
|
|
177
|
+
"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." }
|
|
159
178
|
},
|
|
160
179
|
"additionalProperties": false
|
|
161
180
|
},
|
|
@@ -4,7 +4,7 @@ description: Guia a criação de uma landing page nova ponta-a-ponta a partir do
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao iniciar um novo projeto de LP com o template Umbraco genérico
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.35.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- umbraco
|
|
10
10
|
---
|
|
@@ -4,7 +4,7 @@ description: Migra uma landing page existente (React/Vite, Next.js estático ou
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber instrução "use /migrate-lp-to-umbraco {projeto}" do usuário, ou quando o usuário descrever necessidade de migrar uma LP para Umbraco
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.35.0"
|
|
8
8
|
stacks:
|
|
9
9
|
- umbraco
|
|
10
10
|
---
|
|
@@ -4,7 +4,7 @@ description: Orquestra a execução autônoma de tasks de uma feature morph-spec
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: após Gate 2 aprovado, ao receber instrução "use /morph-apply" ou "implementar feature"
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.35.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-apply
|
|
@@ -96,7 +96,10 @@ while (true):
|
|
|
96
96
|
aplicar feedback priorizado da tentativa anterior ao código já implementado
|
|
97
97
|
|
|
98
98
|
// CÓDIGO ANTES DO JUIZ — barreira determinística e barata (build+testes+validadores).
|
|
99
|
-
|
|
99
|
+
// Loop por task: --filter com os ids das suítes do stack que a task tocou
|
|
100
|
+
// (o relógio de uma task não paga a suíte inteira). Sem project.tests[]
|
|
101
|
+
// declarado há um nó só (`default`) e o --filter não tem o que escolher.
|
|
102
|
+
run: morph-spec verify {feature} {task.id} [--filter {ids-do-stack-da-task}] --json
|
|
100
103
|
if verify.status == 'fail':
|
|
101
104
|
// vermelho: feedback determinístico direto ao loop, SEM gastar o juiz LLM.
|
|
102
105
|
feedback = verify.feedback // usado como input do próximo attempt
|
|
@@ -125,7 +128,9 @@ while (true):
|
|
|
125
128
|
options: [aceitar (marca done com ressalva no recap), continuar tentando (+3 tentativas), pular task (marca blocked)]
|
|
126
129
|
```
|
|
127
130
|
|
|
128
|
-
> **
|
|
131
|
+
> **Loop por task filtra; Gate 3 e CI não.** `--filter {ids}` roda só as suítes do stack que a task tocou — os outros nós **aparecem** em `nodes.tests.runs[]` como `skip` nomeando o filtro, em vez de sumir, e um `--filter` que não casa nada é erro de uso (exit 2), nunca um verde. A verificação pós-batch e a do Gate 3 (`morph-spec verify {feature} --json`) rodam **sem filtro**: a prova que o avaliador lê tem de cobrir todos os nós, e o CI idem. Forma de `project.tests[]` e a tabela da divisão: `.morph/framework/CLI.md`, seção "Suítes de teste".
|
|
132
|
+
>
|
|
133
|
+
> **Verify vermelho consome uma tentativa** do loop (≤3) e devolve `feedback[]` acionável (erros de build, falhas de teste — linhas prefixadas por `[tests/{id}]`, que nomeiam a suíte —, issues de validador). O `morph-eval` NUNCA é invocado sobre código que não passou no verify — o juiz julga arquitetura/contratos/qualidade, o que o código determinístico não pega sozinho. Código roda antes, grátis; o juiz gasta tokens só no que sobra.
|
|
129
134
|
|
|
130
135
|
> **Retry sem re-invoke — e a exceção que evita rodar sem a skill.** `skillLoaded` cai de volta para `false` (forçando reinvocação no próximo attempt) se houver `/compact` OU troca de sessão (nova sessão retomando via `handoff.md`) entre a última invocação e o attempt corrente — os dois eventos podem descartar o conteúdo da skill do seu contexto sem avisar. Sem essa exceção, um retry pós-compact aplicaria feedback sem o mandate/standard/persona carregados. Fora desses dois casos, reinvocar a Skill só para aplicar um feedback pontual é exatamente o custo repetido (~13KB por tentativa) que este corte existe para eliminar.
|
|
131
136
|
>
|
|
@@ -178,18 +183,34 @@ dispatch Agent (subagent_type: "morph-{id}") with prompt:
|
|
|
178
183
|
último ato antes do relatório; reporte a branch — nunca faça merge nem
|
|
179
184
|
toque na árvore principal.
|
|
180
185
|
|
|
186
|
+
4. ESCOPO: no máximo 3 tasks e ~4 arquivos por dispatch. Escopo maior falha e
|
|
187
|
+
volta — fatie antes, não depois.
|
|
188
|
+
5. SOBREVIVÊNCIA: commite `wip({taskId})` ao fim de cada task. Se você parar no
|
|
189
|
+
limite de turnos, é o commit que preserva o trabalho — sem ele, a retomada
|
|
190
|
+
recomeça do zero.
|
|
191
|
+
6. PROCESSOS: NUNCA `taskkill /IM node.exe` (derruba os MCPs de todas as
|
|
192
|
+
sessões). Encerre dev server pelo PID que você mesmo subiu.
|
|
193
|
+
7. RETORNO: o relatório no arquivo canônico é o retorno. `SendMessage` não é
|
|
194
|
+
substituto do relatório e não deve ser chamado.
|
|
195
|
+
|
|
181
196
|
Seu relatório final deve conter APENAS: (1) o que foi feito em 2-3
|
|
182
197
|
frases, (2) arquivos modificados, (3) problemas encontrados e como foram
|
|
183
198
|
resolvidos, (4) auto-score 0-10 com justificativa em uma linha. Relatório
|
|
184
199
|
ausente, oco, ou sem os 4 itens, é falha de protocolo.
|
|
185
200
|
```
|
|
186
201
|
|
|
187
|
-
>
|
|
202
|
+
> **Passo pós-dispatch (do orquestrador, antes de avaliar qualquer relatório):** ao retomar o
|
|
203
|
+
> controle, rode `git status --porcelain src/` e `grep -rn "MUTACAO" src/`. Um sub-agent morto no
|
|
204
|
+
> meio deixa o disco a meio caminho — e um relatório lido sobre uma árvore que ninguém conferiu
|
|
205
|
+
> avalia um estado que ninguém quis. Árvore inesperadamente suja é falha de protocolo: registre no
|
|
206
|
+
> recap antes de pontuar.
|
|
207
|
+
|
|
208
|
+
> Este template é deliberadamente paritário com o template sequencial em `morph-implement` §4: ambos despacham o **subagent registrado do domínio (`morph-{id}`)** com standard escopado e as **mesmas 7 cláusulas** do contrato do relatório final (as 3 do relatório + escopo, sobrevivência, processos e retorno) e os mesmos 4 itens de relatório — racional completo em `MORPH.md` §6. A única diferença é que aqui múltiplos agentes rodam ao mesmo tempo, um por fluxo independente.
|
|
188
209
|
|
|
189
210
|
> **Alternativa quando os fluxos tocam os mesmos projetos/arquivos** (ex.: o mesmo csproj de testes compartilhado): siga a §3b-w abaixo em vez desta seção — despache com `isolation: "worktree"`, cada agente trabalha numa working tree própria e o orquestrador integra ao final.
|
|
190
211
|
|
|
191
212
|
Aguardar todos os agentes terminarem, depois **auditar os relatórios contra o trabalho** com `morph-spec report-check {feature} --json` — determinístico e independente da palavra dos agentes; é o passo que pega tanto o relatório ausente quanto o `report-stale` (completo, porém gravado antes do fim do trabalho: o agente relatou cedo e continuou escrevendo). Em `report-stale`, **não re-despache** — leia o campo `observed` (writes reais do `events.jsonl`) e atualize o relatório a partir dele. Vereditos e ações: `MORPH.md` §6. Em seguida **ler** `.morph/features/{feature}/3-implement/reports/{taskId}.md` de cada task — é o valor de retorno autoritativo; a mensagem de texto do dispatch, se chegou inteira, é só um atalho que economiza essa leitura. Depois, sequencialmente:
|
|
192
|
-
- **Rodar `morph-spec verify {feature} --json` uma única vez, pós-batch** (escopo feature) — os agentes não a rodaram (cláusula 3). Vermelho: use `verify.feedback` para corrigir/redespachar ANTES de qualquer morph-eval. (Com isolamento por worktree, cada agente já rodou o verify dentro do seu worktree; o orquestrador roda o verify compartilhado UMA vez após o merge — ver §3b-w.)
|
|
213
|
+
- **Rodar `morph-spec verify {feature} --json` uma única vez, pós-batch** (escopo feature, **sem `--filter`**) — os agentes não a rodaram (cláusula 3). Vermelho: use `verify.feedback` para corrigir/redespachar ANTES de qualquer morph-eval. (Com isolamento por worktree, cada agente já rodou o verify dentro do seu worktree; o orquestrador roda o verify compartilhado UMA vez após o merge — ver §3b-w.)
|
|
193
214
|
- Para cada relatório retornado:
|
|
194
215
|
- Aplicar `Skill(morph-eval)`.
|
|
195
216
|
- Gravar o score: `morph-spec score {feature} {taskId} {score} --dims {a},{c},{q},{t}`.
|
|
@@ -4,7 +4,7 @@ description: Entende o negócio, os usuários e a arquitetura antes de qualquer
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber um novo request de feature, antes de morph-plan
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.35.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-brainstorming
|
|
@@ -4,7 +4,7 @@ description: Avalia a qualidade de uma tarefa ou fase com rubricas graduadas 0-1
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao completar uma tarefa ou ao finalizar uma fase de implementação
|
|
6
6
|
user-invokable: false
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.35.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-eval
|
|
@@ -4,7 +4,7 @@ description: ADW cirúrgico de hotfix — resolve uma queda/bug crítico de prod
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao receber "/morph-hotfix {feature}", quando a morph-proposal classifica o pedido como workType hotfix (Passo 0), ou o usuário diz "produção caiu / hotfix / urgente"
|
|
6
6
|
user-invokable: true
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.35.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) — não escreve código. Inclua as
|
|
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 escreve código. Inclua as 7 cláusulas do contrato do relatório final no prompt (template literal em `morph-implement` §4 / `morph-apply` §3b): relatório no arquivo canônico como retorno, sem `SendMessage`; não tocar `tasks.json`/`feature.json`/`state.json` nem o board de sessão; sem build/test da suíte compartilhada em batch paralelo; no máximo 3 tasks por dispatch; commit `wip({taskId})` ao fim de cada task; nunca `taskkill /IM node.exe`.
|
|
47
47
|
|
|
48
48
|
### 3. Hotfix brief (`0-proposal/proposal.md`)
|
|
49
49
|
|
|
@@ -4,7 +4,7 @@ description: Guia a execução de cada tarefa de implementação com standard e
|
|
|
4
4
|
version: core
|
|
5
5
|
when-to-invoke: ao iniciar cada task de implementação listada em tasks.json
|
|
6
6
|
user-invokable: false
|
|
7
|
-
cliVersion: "8.
|
|
7
|
+
cliVersion: "8.35.0"
|
|
8
8
|
---
|
|
9
9
|
|
|
10
10
|
# morph-implement
|
|
@@ -87,12 +87,28 @@ Ao iniciar cada task de `tasks.json` — antes de escrever qualquer código. Nor
|
|
|
87
87
|
Worktree não commitado NÃO é removido pelo hook e vira pendência do
|
|
88
88
|
`doctor`; o commit é o que torna o seu trabalho integrável.
|
|
89
89
|
|
|
90
|
+
4. ESCOPO: no máximo 3 tasks e ~4 arquivos por dispatch. Escopo maior falha e
|
|
91
|
+
volta — fatie antes, não depois.
|
|
92
|
+
5. SOBREVIVÊNCIA: commite `wip({taskId})` ao fim de cada task. Se você parar no
|
|
93
|
+
limite de turnos, é o commit que preserva o trabalho — sem ele, a retomada
|
|
94
|
+
recomeça do zero.
|
|
95
|
+
6. PROCESSOS: NUNCA `taskkill /IM node.exe` (derruba os MCPs de todas as
|
|
96
|
+
sessões). Encerre dev server pelo PID que você mesmo subiu.
|
|
97
|
+
7. RETORNO: o relatório no arquivo canônico é o retorno. `SendMessage` não é
|
|
98
|
+
substituto do relatório e não deve ser chamado.
|
|
99
|
+
|
|
90
100
|
Seu relatório (no arquivo, e na mensagem final quando ela chega) deve conter
|
|
91
101
|
APENAS: (1) o que foi feito em 2-3 frases, (2) arquivos modificados,
|
|
92
102
|
(3) problemas encontrados e como foram resolvidos, (4) auto-score 0-10 com
|
|
93
103
|
justificativa em uma linha. Relatório ausente, oco, ou sem os 4 itens, é
|
|
94
104
|
falha de protocolo.
|
|
95
105
|
```
|
|
106
|
+
**Passo pós-dispatch (seu, antes de avaliar o relatório):** rode `git status --porcelain src/`
|
|
107
|
+
e `grep -rn "MUTACAO" src/` ao retomar o controle. Um sub-agent morto no meio deixa o disco a
|
|
108
|
+
meio caminho — e um relatório lido sobre uma árvore que ninguém conferiu avalia um estado que
|
|
109
|
+
ninguém quis. Árvore inesperadamente suja é falha de protocolo: registre no recap antes de
|
|
110
|
+
pontuar.
|
|
111
|
+
|
|
96
112
|
Após o retorno do dispatch: **leia primeiro** `.morph/features/{feature}/3-implement/reports/[ID].md`
|
|
97
113
|
— é o valor de retorno autoritativo. Trate a mensagem de texto do sub-agent, se chegou inteira,
|
|
98
114
|
como um atalho que economiza essa leitura — nunca como a única fonte. Arquivo ausente é falha de
|
|
@@ -181,7 +197,7 @@ Ao iniciar cada task de `tasks.json` — antes de escrever qualquer código. Nor
|
|
|
181
197
|
> tasks.json + recap.md + `taskScores` do feature.json. **NÃO escreva o trace
|
|
182
198
|
> manualmente** — a escrita manual foi removida da cerimônia por task.
|
|
183
199
|
|
|
184
|
-
9. Quando invocada por `morph-apply`, retornar o controle à skill orquestradora — ela decide qual task vem em seguida via `getReadyTasks(data)`. Não rode a suíte de testes inteira do projeto por conta própria ao fim da task quando invocada pela `morph-apply` — a verificação determinística (`morph-spec verify {feature} {task}`) é do orquestrador, logo após seu retorno (ver morph-apply §3a). Quando invocada manualmente, verificar se há próxima task ready e iniciá-la imediatamente aplicando esta skill desde o passo 1 (auto-advance). Pause apenas se encontrar ambiguidade bloqueante não coberta pelo mandate.
|
|
200
|
+
9. Quando invocada por `morph-apply`, retornar o controle à skill orquestradora — ela decide qual task vem em seguida via `getReadyTasks(data)`. Não rode a suíte de testes inteira do projeto por conta própria ao fim da task quando invocada pela `morph-apply` — a verificação determinística (`morph-spec verify {feature} {task} [--filter {ids-do-stack-da-task}]`) é do orquestrador, logo após seu retorno (ver morph-apply §3a). **A divisão:** no loop por task o `--filter` escolhe as suítes do stack que a task tocou (o relógio de uma task não paga a suíte inteira; um nó não casado aparece como `skip` nomeando o filtro, e um filtro que não casa nada é erro de uso, exit 2); a suíte **inteira** roda no Gate 3 e no CI, sem filtro. A suíte completa de um projeto grande não cabe numa invocação de Bash do harness — rode em background ou por partes, nunca "suba o limite" (não há constante de timeout global no CLI). Detalhe e forma de `project.tests[]`: `.morph/framework/CLI.md`, seção "Suítes de teste". Quando invocada manualmente, verificar se há próxima task ready e iniciá-la imediatamente aplicando esta skill desde o passo 1 (auto-advance). Pause apenas se encontrar ambiguidade bloqueante não coberta pelo mandate.
|
|
185
201
|
|
|
186
202
|
## Output esperado
|
|
187
203
|
- Código implementado conforme o standard consultado (direto ou via sub-agent)
|