@polymorphism-tech/morph-spec 8.28.0 → 8.31.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.
Files changed (185) hide show
  1. package/CLAUDE.md +6 -1
  2. package/README.md +13 -2
  3. package/bin/morph-spec.js +48 -0
  4. package/bin/validate.js +379 -379
  5. package/claude-plugin.json +1 -1
  6. package/docs/CHEATSHEET.md +1 -1
  7. package/docs/QUICKSTART.md +1 -1
  8. package/framework/CLAUDE.md +2 -0
  9. package/framework/MORPH.md +2 -1
  10. package/framework/agents.json +20 -9
  11. package/framework/commands/create-umbraco-lp.md +1 -1
  12. package/framework/commands/morph-status.md +1 -1
  13. package/framework/docs/CLI.md +18 -0
  14. package/framework/evals/rubrics/code-quality.md +17 -0
  15. package/framework/evals/rubrics/condensed.md +3 -1
  16. package/framework/hooks/claude-code/statusline.sh +11 -11
  17. package/framework/hooks/git/commit-msg/conventional-commits.sh +33 -33
  18. package/framework/hooks/git/pre-commit/agents.sh +25 -25
  19. package/framework/hooks/git/pre-commit/orchestrator.sh +64 -64
  20. package/framework/hooks/git/pre-commit/specs.sh +50 -50
  21. package/framework/hooks/git/pre-push/run-tests.sh +44 -44
  22. package/framework/hooks/shared/phase-utils.js +2 -0
  23. package/framework/hooks/shared/stdin-reader.js +26 -26
  24. package/framework/mcp/registry.json +97 -11
  25. package/framework/rubrics/backend.json +2 -2
  26. package/framework/rubrics/default.json +2 -2
  27. package/framework/rubrics/frontend.json +2 -2
  28. package/framework/schemas/tasks.schema.json +25 -0
  29. package/framework/skills/core/create-umbraco-lp/SKILL.md +13 -2
  30. package/framework/skills/core/create-umbraco-lp/references/umbraco-lp-patterns.md +598 -0
  31. package/framework/skills/core/migrate-lp-to-umbraco/SKILL.md +92 -7
  32. package/framework/skills/core/morph-apply/SKILL.md +12 -3
  33. package/framework/skills/core/morph-brainstorming/SKILL.md +1 -1
  34. package/framework/skills/core/morph-eval/SKILL.md +1 -1
  35. package/framework/skills/core/morph-hotfix/SKILL.md +1 -1
  36. package/framework/skills/core/morph-implement/SKILL.md +12 -2
  37. package/framework/skills/core/morph-plan/SKILL.md +45 -3
  38. package/framework/skills/core/morph-proposal/SKILL.md +1 -1
  39. package/framework/skills/core/morph-review/SKILL.md +11 -3
  40. package/framework/skills/core/morph-stack-scan/SKILL.md +13 -1
  41. package/framework/skills/core/morph-standards/SKILL.md +1 -1
  42. package/framework/skills/core/morph-uiux/SKILL.md +1 -1
  43. package/framework/standards/PROVENANCE.json +41 -0
  44. package/framework/standards/STANDARDS.json +218 -7
  45. package/framework/standards/ai-agents/agent-session.md +160 -160
  46. package/framework/standards/ai-agents/batching.md +193 -193
  47. package/framework/standards/ai-agents/context-providers.md +188 -188
  48. package/framework/standards/ai-agents/mcp-server.md +250 -250
  49. package/framework/standards/ai-agents/mcp-tools.md +197 -197
  50. package/framework/standards/ai-agents/middleware-patterns.md +207 -207
  51. package/framework/standards/ai-agents/modalities-image-gen.md +173 -173
  52. package/framework/standards/ai-agents/modalities-speech-to-text.md +171 -171
  53. package/framework/standards/ai-agents/modalities-text-to-speech.md +181 -181
  54. package/framework/standards/ai-agents/modalities-vision.md +201 -201
  55. package/framework/standards/ai-agents/multi-agent-patterns.md +155 -155
  56. package/framework/standards/ai-agents/production.md +231 -231
  57. package/framework/standards/ai-agents/prompts-in-db.md +214 -214
  58. package/framework/standards/ai-agents/providers/model-registry.md +158 -158
  59. package/framework/standards/ai-agents/service-tier-flex.md +135 -135
  60. package/framework/standards/ai-agents/structured-output.md +249 -249
  61. package/framework/standards/ai-agents/sweet-spot.md +109 -109
  62. package/framework/standards/frontend/design-system/ai-image-generation.md +43 -0
  63. package/framework/standards/frontend/design-system/ai-video-generation.md +113 -0
  64. package/framework/standards/frontend/design-system/premium-finish.md +160 -0
  65. package/framework/standards/frontend/gsap/gsap-core.md +1 -1
  66. package/framework/standards/frontend/gsap/gsap-plugins.md +1 -1
  67. package/framework/standards/frontend/gsap/gsap-scrolltrigger.md +3 -1
  68. package/framework/standards/frontend/nextjs/motion-patterns.md +3 -1
  69. package/framework/standards/frontend/scroll-driven/frame-scrub.md +287 -0
  70. package/framework/standards/frontend/scroll-driven/scroll-components.md +256 -0
  71. package/framework/standards/frontend/scroll-driven/smooth-scroll.md +148 -0
  72. package/framework/standards/frontend/seo/meta-schema-audit.md +134 -0
  73. package/framework/templates/.idea/morph-templates.xml +92 -0
  74. package/framework/templates/.vscode/morph-templates.code-snippets +186 -0
  75. package/framework/templates/IDE-SNIPPETS.md +262 -262
  76. package/framework/templates/code/dotnet/abstractions/api-endpoint.cs +7 -7
  77. package/framework/templates/code/dotnet/ai-agents/AgentBootstrap.cs.template +39 -39
  78. package/framework/templates/code/dotnet/ai-agents/EmbeddingService.cs.template +68 -68
  79. package/framework/templates/code/dotnet/ai-agents/ModelRegistry.cs.template +117 -117
  80. package/framework/templates/code/dotnet/ai-agents/PromptRepository.cs.template +95 -95
  81. package/framework/templates/code/dotnet/ai-agents/ResilientToolMiddleware.cs.template +61 -61
  82. package/framework/templates/code/dotnet/ai-agents/VectorSearchTool.cs.template +107 -107
  83. package/framework/templates/code/dotnet/ai-agents/model-registry.json.template +58 -58
  84. package/framework/templates/code/dotnet/contracts/contracts-vsa.cs +281 -281
  85. package/framework/templates/code/dotnet/database/migration.cs +83 -83
  86. package/framework/templates/code/dotnet/feature/endpoint.cs.hbs +21 -21
  87. package/framework/templates/code/dotnet/feature/request.cs.hbs +4 -4
  88. package/framework/templates/code/dotnet/feature/response.cs.hbs +4 -4
  89. package/framework/templates/code/dotnet/feature/validator.cs.hbs +15 -15
  90. package/framework/templates/code/sql/ai-agents/agent-prompts-migration.sql.template +58 -58
  91. package/framework/templates/code/sql/ai-agents/pgvector-embeddings-migration.sql.template +91 -91
  92. package/framework/templates/code/typescript/contracts.ts +167 -167
  93. package/framework/templates/context/ARCHITECTURE.md +20 -0
  94. package/framework/templates/docs/clarifications.md +253 -253
  95. package/framework/templates/docs/schema-analysis.md +119 -119
  96. package/framework/templates/docs/ui-components.md +52 -52
  97. package/framework/templates/docs/ui-design-system.md +76 -76
  98. package/framework/templates/docs/ui-flows.md +167 -167
  99. package/framework/templates/docs/ui-mockups.md +98 -98
  100. package/framework/templates/feature/decisions.md +122 -122
  101. package/framework/templates/frontend/nextjs/Dockerfile.nextjs.hbs +43 -43
  102. package/framework/templates/frontend/nextjs/client-component.tsx.hbs +26 -26
  103. package/framework/templates/frontend/nextjs/env.mjs.hbs +32 -32
  104. package/framework/templates/frontend/nextjs/feature-form.tsx.hbs +56 -56
  105. package/framework/templates/frontend/nextjs/page.tsx.hbs +22 -22
  106. package/framework/templates/frontend/nextjs/tsconfig.json.hbs +26 -26
  107. package/framework/templates/frontend/nextjs/use-feature.ts.hbs +54 -54
  108. package/framework/templates/infrastructure/docker/Dockerfile.template +58 -58
  109. package/framework/templates/infrastructure/docker/dockerfile-api.dockerfile +38 -38
  110. package/framework/templates/infrastructure/docker/dockerfile-web.dockerfile +48 -48
  111. package/framework/templates/infrastructure/github/README.md +56 -56
  112. package/framework/templates/infrastructure/github/actions/docker-build-push/action.yml.hbs +45 -45
  113. package/framework/templates/infrastructure/github/actions/health-check/action.yml.hbs +27 -27
  114. package/framework/templates/infrastructure/github/workflows/docker-build-push.yml.hbs +59 -59
  115. package/framework/templates/infrastructure/github/workflows/dotnet-build.yml.hbs +39 -39
  116. package/framework/templates/integrations/asaas-client.cs +387 -387
  117. package/framework/templates/integrations/asaas-webhook.cs +351 -351
  118. package/framework/templates/meta-prompts/fusion/fusion-agent.md +76 -76
  119. package/framework/templates/meta-prompts/fusion/fusion-aggregator.md +100 -100
  120. package/framework/templates/meta-prompts/validators/pre-commit-validator.md +95 -95
  121. package/framework/templates/project/validate.js +120 -120
  122. package/framework/templates/state.template.json +17 -17
  123. package/framework/templates/ui/design-system.css +226 -226
  124. package/package.json +1 -1
  125. package/src/commands/dashboard/dashboard.js +53 -53
  126. package/src/commands/graph/affected.js +89 -0
  127. package/src/commands/graph/build.js +94 -0
  128. package/src/commands/graph/explain.js +96 -0
  129. package/src/commands/graph/status.js +93 -0
  130. package/src/commands/index.js +13 -13
  131. package/src/commands/project/checkpoint.js +209 -209
  132. package/src/commands/project/doctor.js +11 -0
  133. package/src/core/paths/output-schema.js +7 -0
  134. package/src/core/state/phase-state-machine.js +197 -197
  135. package/src/core/templates/template-renderer.js +477 -477
  136. package/src/dashboard/app/components/DetailPanel.jsx +11 -11
  137. package/src/dashboard/app/components/FlowGraph.jsx +17 -17
  138. package/src/dashboard/app/components/SearchFilter.jsx +22 -22
  139. package/src/dashboard/app/hooks/useDetailPanel.js +15 -15
  140. package/src/dashboard/app/main.jsx +13 -13
  141. package/src/dashboard/app/pages/AgentMap.jsx +370 -370
  142. package/src/dashboard/app/pages/HookInspector.jsx +418 -418
  143. package/src/dashboard/app/pages/PhasePipeline.jsx +408 -408
  144. package/src/dashboard/app/pages/RulesMap.jsx +273 -273
  145. package/src/dashboard/app/pages/SkillsLibrary.jsx +366 -366
  146. package/src/dashboard/app/pages/Standards.jsx +332 -332
  147. package/src/dashboard/app/styles/index.css +47 -47
  148. package/src/dashboard/index.html +12 -12
  149. package/src/dashboard/package.json +24 -24
  150. package/src/dashboard/scanner/phases-scanner.js +15 -15
  151. package/src/dashboard/scanner/rubrics-scanner.js +12 -12
  152. package/src/dashboard/scanner/rules-scanner.js +37 -37
  153. package/src/dashboard/scanner/skills-scanner.js +43 -43
  154. package/src/dashboard/scanner/squads-scanner.js +13 -13
  155. package/src/dashboard/vite-plugin-morph-data.js +17 -17
  156. package/src/dashboard/vite.config.js +24 -24
  157. package/src/lib/detectors/design-system-detector.js +188 -188
  158. package/src/lib/detectors/index.js +217 -217
  159. package/src/lib/generators/architecture-scanner.js +45 -4
  160. package/src/lib/generators/design-system-generator.js +508 -508
  161. package/src/lib/generators/settings-generator.js +209 -209
  162. package/src/lib/graph/god-nodes.js +75 -0
  163. package/src/lib/graph/graph-health.js +61 -0
  164. package/src/lib/graph/graph-loader.js +86 -0
  165. package/src/lib/graph/graphify-runtime.js +100 -0
  166. package/src/lib/graph/graphifyignore.js +86 -0
  167. package/src/lib/graph/sanitize.js +280 -0
  168. package/src/lib/hooks/hook-executor.js +167 -167
  169. package/src/lib/installers/mcp-installer.js +719 -719
  170. package/src/lib/tasks/task-classifier.js +30 -30
  171. package/src/lib/tasks/task-parser.js +209 -209
  172. package/src/lib/tasks/tasks-json-parser.js +26 -0
  173. package/src/lib/validators/checkpoint-persistence.js +39 -39
  174. package/src/lib/validators/css/css-validator.js +340 -340
  175. package/src/lib/validators/reuse/index.js +10 -0
  176. package/src/lib/validators/reuse/reuse-validator.js +324 -0
  177. package/src/lib/validators/reuse/symbol-scanner.js +144 -0
  178. package/src/lib/validators/shared/emit-validator-dispatch.js +14 -14
  179. package/src/lib/validators/shared/issue-counter.js +14 -14
  180. package/src/lib/validators/validation-runner.js +40 -1
  181. package/src/scripts/setup-infra.js +60 -1
  182. package/src/utils/agent-id-mapper.js +11 -11
  183. package/src/utils/claude-settings-manager.js +300 -300
  184. package/src/utils/file-copier.js +40 -0
  185. package/src/utils/skills-installer.js +187 -187
@@ -1226,7 +1226,7 @@
1226
1226
  "react"
1227
1227
  ],
1228
1228
  "stacks": [
1229
- "nextjs"
1229
+ "*"
1230
1230
  ],
1231
1231
  "aliases": [
1232
1232
  "GSAP",
@@ -1260,7 +1260,7 @@
1260
1260
  "scroll-animation"
1261
1261
  ],
1262
1262
  "stacks": [
1263
- "nextjs"
1263
+ "*"
1264
1264
  ],
1265
1265
  "aliases": [
1266
1266
  "ScrollTrigger",
@@ -1290,7 +1290,7 @@
1290
1290
  "plugins"
1291
1291
  ],
1292
1292
  "stacks": [
1293
- "nextjs"
1293
+ "*"
1294
1294
  ],
1295
1295
  "aliases": [
1296
1296
  "Flip",
@@ -1695,21 +1695,30 @@
1695
1695
  "mcp"
1696
1696
  ],
1697
1697
  "stacks": [
1698
- "nextjs"
1698
+ "*"
1699
1699
  ],
1700
1700
  "aliases": [
1701
1701
  "Image Generation",
1702
1702
  "AI Assets",
1703
- "Gemini Images"
1703
+ "Gemini Images",
1704
+ "brand fidelity",
1705
+ "reference images",
1706
+ "favicon",
1707
+ "og image",
1708
+ "asset generation"
1704
1709
  ],
1705
1710
  "anchors": {
1706
1711
  "when-to-use": "#when-to-use-ai-generated-images",
1707
1712
  "prompt-patterns": "#prompt-engineering-patterns",
1708
1713
  "aspect-ratios": "#aspect-ratio-guide",
1709
1714
  "assets-md": "#assetsmd-format",
1710
- "edit-workflows": "#iterative-editing-workflows"
1715
+ "edit-workflows": "#iterative-editing-workflows",
1716
+ "brand-fidelity": "#brand-fidelity-reference-dont-invent",
1717
+ "to-video": "#downstream-images-that-become-video",
1718
+ "favicon-og": "#the-two-assets-everyone-forgets",
1719
+ "variations": "#variations-and-cost"
1711
1720
  },
1712
- "digest": "Guidelines for generating project images with Gemini Image MCP — prompt patterns, aspect ratios, design-system-aware prompts, iterative editing, and assets.md format."
1721
+ "digest": "Guidelines for generating project images with the Gemini Image MCP: when to use AI versus stock versus SVG, prompt patterns, aspect ratios, iterative editing and assets.md format. Core principle is brand fidelity over invention: always pass the client's real assets as referenceImages via edit_image rather than generating in a vacuum, never AI-recreate a property developer's architectural render or a physical product (animate or reference the real one), and chain derivatives from an approved hero so the whole set shares light, palette and identity. Frame anything destined to become video WITHOUT a face, because video moderation is stricter (E005), and generate scrub frames at the video's exact ratio with the subject opposite the copy. Always produce the two forgotten assets: a favicon derived from the real logo (never a new one) and a 1200x630 OG share image. Offer two to three genuinely different variations per image, varying angle, light or composition rather than the seed, and never advance with a weak image because every derivative inherits it."
1713
1722
  },
1714
1723
  {
1715
1724
  "id": "ai-agents-durable-workflows-hitl",
@@ -1807,6 +1816,208 @@
1807
1816
  "errorbody": "#rule-2--error-path-tests-assert-the-response-body-not-just-the-status-code"
1808
1817
  },
1809
1818
  "digest": "Inject TimeProvider (never DateTime.UtcNow / DateOnly.FromDateTime(DateTime.UtcNow) directly in a handler or validator) and fake it with FakeTimeProvider (Microsoft.Extensions.TimeProvider.Testing) in integration tests — deterministic, no midnight-UTC flake, boundary dates (today vs. yesterday) become facts about the fake clock instead of when the suite happens to run. xUnit + WebApplicationFactory error-path tests (400/404/409) must assert the ProblemDetails response BODY (title/detail/violated field or error code), never just the HTTP status code — a status-only assertion lets the wrong validation rule or the wrong error branch pass silently as long as the status matches."
1819
+ },
1820
+ {
1821
+ "id": "frontend-scroll-driven-frame-scrub",
1822
+ "name": "frame scrub",
1823
+ "path": "frontend/scroll-driven/frame-scrub.md",
1824
+ "category": "frontend",
1825
+ "subcategory": "scroll-driven",
1826
+ "tags": [
1827
+ "frontend",
1828
+ "scroll-driven",
1829
+ "motion"
1830
+ ],
1831
+ "stacks": [
1832
+ "*"
1833
+ ],
1834
+ "aliases": [
1835
+ "frame scrub",
1836
+ "canvas scrub",
1837
+ "scroll-driven video",
1838
+ "scrollytelling video",
1839
+ "apple scroll video",
1840
+ "ffmpeg frames",
1841
+ "poster fallback"
1842
+ ],
1843
+ "anchors": {
1844
+ "why": "#section-1-canvas-not-video-currenttime",
1845
+ "extraction": "#section-2-frame-extraction",
1846
+ "cachebust": "#section-3-cache-busting-is-mandatory",
1847
+ "bug": "#section-5-the-1x1-canvas-bug",
1848
+ "responsive": "#section-6-responsive-and-reduced-motion",
1849
+ "verify": "#section-8-verify-with-motion-never-with-a-still"
1850
+ },
1851
+ "digest": "Scroll-driven video is a preloaded JPG sequence drawn into a <canvas>, never a <video currentTime> driven by scroll (unreliable seek on iOS Safari, black-frame flashes) and never an autoplay loop (reads as a demo, not as user-driven). Extract with ffmpeg (fps=30, ~120-300 frames, -q:v 5), always extract a poster, hflip when the subject collides with the copy, and treat total sequence weight as a performance budget. Always cache-bust the frame URL (?v=N) when re-extracting under the same filenames. Known bug: a section starting hidden measures 0 and the canvas becomes 1x1 drawing one stretched pixel, so keep the canvas display:none and resize on the first loaded frame. Mobile and prefers-reduced-motion collapse to the static poster in both the JS guard and the CSS. Verify by driving the scroll through positions and comparing captured frames (allow ~350ms for scrub:0.4 to settle), never with a single screenshot."
1852
+ },
1853
+ {
1854
+ "id": "frontend-scroll-driven-smooth-scroll",
1855
+ "name": "smooth scroll",
1856
+ "path": "frontend/scroll-driven/smooth-scroll.md",
1857
+ "category": "frontend",
1858
+ "subcategory": "scroll-driven",
1859
+ "tags": [
1860
+ "frontend",
1861
+ "scroll-driven",
1862
+ "motion"
1863
+ ],
1864
+ "stacks": [
1865
+ "*"
1866
+ ],
1867
+ "aliases": [
1868
+ "lenis",
1869
+ "smooth scroll",
1870
+ "scroll wiring",
1871
+ "gsap ticker",
1872
+ "window.__lenis",
1873
+ "scrolltrigger refresh",
1874
+ "HMR stale triggers"
1875
+ ],
1876
+ "anchors": {
1877
+ "registry": "#section-1-central-motion-registry",
1878
+ "raf": "#section-2-the-raf-handoff",
1879
+ "expose": "#section-3-expose-the-instance-on-window",
1880
+ "hmr": "#section-4-the-hmr-staleness-trap"
1881
+ },
1882
+ "digest": "Register GSAP plugins once in a shared lib/motion module that also exports prefersReducedMotion. Drive Lenis from gsap.ticker (never its own RAF loop), bind lenis.on(scroll, ScrollTrigger.update), set gsap.ticker.lagSmoothing(0), and call ScrollTrigger.refresh() on window load so triggers re-measure after fonts and images settle. Expose window.__lenis deliberately: overlays need stop()/start() to freeze the background, and automated verification needs scrollTo(y, {immediate:true}) to step through positions; consumers must use optional chaining because the instance is never created under reduced motion. After many hot reloads ScrollTrigger accumulates stale instances and pins/scrubs silently die, so full-reload before debugging, wrap every effect in gsap.context()/matchMedia() with revert on cleanup, and set invalidateOnRefresh on viewport-dependent triggers."
1883
+ },
1884
+ {
1885
+ "id": "frontend-scroll-driven-scroll-components",
1886
+ "name": "scroll components",
1887
+ "path": "frontend/scroll-driven/scroll-components.md",
1888
+ "category": "frontend",
1889
+ "subcategory": "scroll-driven",
1890
+ "tags": [
1891
+ "frontend",
1892
+ "scroll-driven",
1893
+ "motion"
1894
+ ],
1895
+ "stacks": [
1896
+ "*"
1897
+ ],
1898
+ "aliases": [
1899
+ "pinned gallery",
1900
+ "horizontal scroll",
1901
+ "scroll reveal",
1902
+ "parallax drift",
1903
+ "count-up",
1904
+ "lightbox",
1905
+ "scroll progress",
1906
+ "expanding modal"
1907
+ ],
1908
+ "anchors": {
1909
+ "reveal": "#section-1-usereveal-the-base-brick",
1910
+ "pinned": "#section-2-pinned-horizontal-gallery",
1911
+ "overlays": "#section-3-expanding-modal",
1912
+ "parallax": "#section-5-parallax-drift",
1913
+ "rules": "#section-9-cross-cutting-rules"
1914
+ },
1915
+ "digest": "Toolbox of scroll-driven interaction patterns, not a mandatory list: useReveal (fade/rise with once:true) covers most content; pinned horizontal gallery needs invalidateOnRefresh:true or the travel distance stays frozen after a resize; expanding modal and lightbox mount then add an .in class on the next frame, pause the scroller via window.__lenis?.stop(), and must render OUTSIDE any pinned section because the pin transform breaks position:fixed inside it; parallax drift stays subtle at 5-8% with overflow:hidden on the figure; count-up animates a plain object and formats per locale; scroll progress uses scaleX with transform-origin 0 50% to stay on the compositor; accordions use native <details>. Cross-cutting: anything clickable that is not a button or anchor gets role=button, tabIndex 0 and Enter/Space, Escape closes overlays, every effect has a static reduced-motion fallback and reverts on cleanup."
1916
+ },
1917
+ {
1918
+ "id": "frontend-design-system-premium-finish",
1919
+ "name": "premium finish",
1920
+ "path": "frontend/design-system/premium-finish.md",
1921
+ "category": "frontend",
1922
+ "subcategory": "design-system",
1923
+ "tags": [
1924
+ "frontend",
1925
+ "design-system"
1926
+ ],
1927
+ "stacks": [
1928
+ "*"
1929
+ ],
1930
+ "aliases": [
1931
+ "premium finish",
1932
+ "polish layer",
1933
+ "film grain",
1934
+ "atmosphere",
1935
+ "load-in stagger",
1936
+ "scrim",
1937
+ "text over video",
1938
+ "metallic accent",
1939
+ "looks like a template"
1940
+ ],
1941
+ "anchors": {
1942
+ "typography": "#section-1-typography-with-character",
1943
+ "atmosphere": "#section-2-atmosphere-never-flat-color",
1944
+ "loadin": "#section-3-one-orchestrated-load-in-beats-ten-micro-interactions",
1945
+ "legibility": "#section-4-legibility-over-video-close-to-a-hard-rule",
1946
+ "order": "#section-7-order-of-application"
1947
+ },
1948
+ "digest": "The finish layer that separates a working build from one a client reads as expensive, applied from the start rather than as a final polish pass. Principles, never a fixed recipe, and never converge on the same choices across projects: commit to a display font chosen from the brand (stack defaults and the AI-tell faces like Space Grotesk/Playfair announce machine-generated); use atmosphere instead of flat color (feTurbulence film grain at low opacity, radial brand glow, vignette); concentrate effort on ONE orchestrated hero load-in with staggered animation-delay rather than scattered micro-interactions; text over media always gets a DIRECTIONAL scrim (dark where the copy lives, clear over the subject) plus text-shadow as insurance against bright frames; one precious accent used in three places or fewer. Define brand tokens as CSS variables first, then atmosphere, then hero, then accent, then details."
1949
+ },
1950
+ {
1951
+ "id": "frontend-seo-meta-schema-audit",
1952
+ "name": "meta schema audit",
1953
+ "path": "frontend/seo/meta-schema-audit.md",
1954
+ "category": "frontend",
1955
+ "subcategory": "seo",
1956
+ "tags": [
1957
+ "frontend",
1958
+ "seo",
1959
+ "accessibility"
1960
+ ],
1961
+ "stacks": [
1962
+ "*"
1963
+ ],
1964
+ "aliases": [
1965
+ "seo",
1966
+ "meta tags",
1967
+ "open graph",
1968
+ "og:image",
1969
+ "schema.org",
1970
+ "json-ld",
1971
+ "rich results",
1972
+ "lighthouse",
1973
+ "go-live audit",
1974
+ "canonical"
1975
+ ],
1976
+ "anchors": {
1977
+ "meta": "#section-1-essential-meta",
1978
+ "opengraph": "#section-2-open-graph-and-twitter-cards",
1979
+ "schema": "#section-3-schemaorg-json-ld-by-business-type",
1980
+ "a11y": "#section-4-accessibility-also-an-seo-signal",
1981
+ "audit": "#section-5-pre-launch-audit"
1982
+ },
1983
+ "digest": "Head-level SEO is cheap and pays for itself: title/description/canonical/theme-color/favicon, correct lang, font preconnects, and a full Open Graph set with an absolute 1200x630 og:image (without it a pasted link renders as a bare card). Pick the JSON-LD @type from the business (ClothingStore/Store for retail, LocalBusiness for services, RealEstateAgent or Residence for property, SoftwareApplication for SaaS) and include ONLY true fields: aggregateRating goes in only with a real rating and review count from a real source, otherwise omit the block, because fabricated structured data is a trust and manual-action risk. Accessibility doubles as an SEO signal (alt text, contrast checked against the brightest frames, focus order, one h1, reduced-motion honored). Before go-live run Lighthouse, a clean-console check, a share-card check and cross-device; if a heavy frame sequence costs Performance, confirm the cost sits in the scrub and state the trade rather than letting a low score pass unexamined."
1984
+ },
1985
+ {
1986
+ "id": "frontend-design-system-ai-video-generation",
1987
+ "name": "AI Video Generation",
1988
+ "path": "frontend/design-system/ai-video-generation.md",
1989
+ "category": "frontend",
1990
+ "subcategory": "design-system",
1991
+ "tags": [
1992
+ "video",
1993
+ "seedance",
1994
+ "asset",
1995
+ "ai-generation",
1996
+ "motion",
1997
+ "mcp"
1998
+ ],
1999
+ "stacks": [
2000
+ "*"
2001
+ ],
2002
+ "aliases": [
2003
+ "video generation",
2004
+ "seedance",
2005
+ "img2vid",
2006
+ "endImage",
2007
+ "directional footage",
2008
+ "loop video",
2009
+ "E005",
2010
+ "animate render",
2011
+ "scroll scrub footage"
2012
+ ],
2013
+ "anchors": {
2014
+ "loop-vs-directional": "#section-1-the-distinction-that-decides-everything",
2015
+ "directional": "#section-2-building-directional-footage",
2016
+ "moderation": "#section-3-faces-trip-moderation",
2017
+ "cost-ladder": "#section-4-the-cost-ladder",
2018
+ "prompt-skeleton": "#section-5-prompt-skeleton"
2019
+ },
2020
+ "digest": "The decisive rule: a perfect loop has an end frame identical to its start, which is right for a self-playing ambient background and WRONG for scroll scrubbing, because start and end look the same and the page reads as frozen while the user scrolls. Scroll-driven footage needs directional movement via generate_video with an endImage (push-in/dolly is the most reliable, then reveal, pull-back, slow tilt); avoid orbits and any movement that returns to its origin. Client architectural renders are animated with img2vid, never AI-recreated. Human faces repeatedly trip moderation (E005), so crop the face out of frame (neck down, hands, product) and reserve faces for static image generation. Always climb the cost ladder: fast/480p/4s draft to judge framing and movement, 1080p only after approval, then re-extract frames with a bumped cache-bust. Prompts read like director notes with no hype words, and must reserve a calm dark region for the page copy with the subject on the opposite side. Generation is async: generate_video returns a request_id polled via get_video; list_videos reads local history and spends no credits."
1810
2021
  }
1811
2022
  ],
1812
2023
  "sharedAliases": {
@@ -1,160 +1,160 @@
1
- # Agent Session — Conversation state and chat reducers
2
-
3
- > **Scope:** stacks=["dotnet"]
4
- > **Layer:** 2 (on-keyword)
5
- > **Keywords:** agent session, chat history, conversation state, chat reducer, history truncation, AgentThread
6
- > **Read by Claude in:** implement
7
-
8
- **Verified against:** MAF 1.0 GA. Last-verified: 2026-05-19.
9
-
10
- ---
11
-
12
- ## Quando usar AgentSession
13
-
14
- Use `AgentSession` quando o agente é **conversacional** — há uma UI de chat que mantém histórico entre turnos do usuário.
15
-
16
- **Use AgentSession quando:**
17
- - Existe uma interface de chat (web, mobile, CLI interativo)
18
- - O agente precisa lembrar o que foi dito nos turnos anteriores da mesma conversa
19
- - Há perguntas de follow-up ("e agora?", "altere o segundo ponto", "lembra do que disse sobre X?")
20
-
21
- **NÃO use AgentSession quando:**
22
- - O agente é one-shot (gerador, executor, classificador) — recebe uma entrada, devolve uma saída, fim
23
- - Agentes stateless em pipeline multi-agent — cada chamada é independente
24
- - Jobs de batch/background — não há conversa; histórico não faz sentido
25
-
26
- > "Add Memory/Session because agents need state" é um anti-pattern de `sweet-spot.md`.
27
- > Só adicione quando uma UI de chat real existe.
28
-
29
- ---
30
-
31
- ## A API
32
-
33
- **Pacote:** `Microsoft.Agents.AI` (base; já requerido por `ai-agents-setup`).
34
-
35
- **Tipos confirmados via context7:**
36
- - `AgentSession` — container leve de estado de conversa; obtido via `agent.CreateSessionAsync()`
37
- - `AgentThread` — equivalente para agentes persistentes (PersistentAgentsClient); use `agent.GetNewThread()`
38
- - `ChatClientAgentOptions` — aceita `ChatHistoryProvider` e `AIContextProviders`
39
- - `InMemoryChatHistoryProvider` — implementação embutida de histórico em memória
40
- - `AgentResponse` — tipo retornado por `AIAgent.RunAsync` (non-generic); acesse o texto via `.Text`
41
-
42
- ```csharp
43
- // Construção do agente com histórico em memória
44
- AIAgent agent = _modelRegistry.GetChatClient("text-default")
45
- .AsAIAgent(new ChatClientAgentOptions
46
- {
47
- ChatOptions = new() { Instructions = "You are a helpful assistant." },
48
- ChatHistoryProvider = new InMemoryChatHistoryProvider(),
49
- });
50
- ```
51
-
52
- ---
53
-
54
- ## Exemplo C# — agente conversacional com session persistente entre turnos
55
-
56
- ```csharp
57
- using Microsoft.Agents.AI;
58
- using Microsoft.Extensions.AI;
59
-
60
- // ── 1. Registrar o agente conversacional no DI ──
61
- // Program.cs
62
- builder.Services.AddSingleton<AIAgent>(sp =>
63
- {
64
- var registry = sp.GetRequiredService<ModelRegistry>();
65
- return registry.GetChatClient("text-default")
66
- .AsAIAgent(new ChatClientAgentOptions
67
- {
68
- ChatOptions = new() { Instructions = "You are a helpful customer support assistant." },
69
- // InMemoryChatHistoryProvider: histórico vive em memória, por session.
70
- // Seguro registrar como parte do singleton AIAgent: cada AgentSession criada via
71
- // agent.CreateSessionAsync() isola o histórico de sua conversa — conversas distintas
72
- // não compartilham estado. O provider em si é stateless; o estado fica na session.
73
- // Para persistência entre restarts, substitua por um provider customizado (ex: DB).
74
- ChatHistoryProvider = new InMemoryChatHistoryProvider(),
75
- });
76
- });
77
-
78
- // ── 2. Criar uma session por conversa (ex: por conexão SignalR / por request de "start chat") ──
79
- // ChatController.cs ou ChatHub.cs
80
- public class ChatService(AIAgent _agent)
81
- {
82
- // Uma session por conversa ativa — armazene no escopo do usuário (cache, memória da conexão)
83
- public async Task<AgentSession> StartConversationAsync()
84
- => await _agent.CreateSessionAsync();
85
-
86
- // Cada mensagem do usuário passa a mesma session
87
- public async Task<string> SendMessageAsync(AgentSession session, string userMessage)
88
- {
89
- AgentResponse response = await _agent.RunAsync(userMessage, session);
90
- return response.Text;
91
- }
92
- }
93
-
94
- // ── 3. Uso no controller/hub ──
95
- // Primeiro turno
96
- AgentSession session = await chatService.StartConversationAsync();
97
- string reply1 = await chatService.SendMessageAsync(session, "Meu pedido #1234 está atrasado.");
98
- // reply1: "Vou verificar o pedido #1234 para você..."
99
-
100
- // Segundo turno — o agente lembra do contexto anterior
101
- string reply2 = await chatService.SendMessageAsync(session, "E quando foi despachado?");
102
- // reply2: "O pedido #1234 foi despachado em..." ← contexto mantido pela session
103
- ```
104
-
105
- ---
106
-
107
- ## History management
108
-
109
- O histórico cresce a cada turno. Quando estoura o context window do modelo, as chamadas falham ou truncam silenciosamente.
110
-
111
- ### Estratégias
112
-
113
- | Estratégia | Quando usar | Como implementar |
114
- |------------|-------------|------------------|
115
- | **Sliding window** | Conversas longas com contexto recente suficiente | Limitar `InMemoryChatHistoryProvider` a N mensagens mais recentes |
116
- | **Token budget** | Modelos com context window pequeno | Contar tokens acumulados; truncar quando ultrapassa threshold |
117
- | **Summarization** | Histórico precisa de contexto antigo comprimido | Agente periódico que resume N turnos anteriores em uma mensagem única |
118
-
119
- > **Custom history management:** Para o caso comum, `InMemoryChatHistoryProvider` cobre a
120
- > necessidade de histórico em memória por sessão. Se o projeto exigir truncation customizada
121
- > (ex: sliding window limitando a N mensagens mais recentes ou por token budget), o mecanismo
122
- > de extensão correto — seja subclasse de `ChatHistoryProvider`, um `IChatReducer`, ou outro
123
- > ponto de override — deve ser verificado contra a versão instalada de `Microsoft.Agents.AI`.
124
- > Consulte a documentação MAF atual antes de implementar um provider customizado, pois a API
125
- > exata de extensão não foi confirmada na versão GA e pode variar entre releases.
126
-
127
- ---
128
-
129
- ## Anti-patterns
130
-
131
- | Anti-pattern | Problema |
132
- |-------------|----------|
133
- | Adicionar session em agente one-shot (gerador, executor) | Complexidade desnecessária; estado nunca é usado |
134
- | Histórico ilimitado sem truncation | Context window estoura; custo aumenta linearmente com a conversa |
135
- | Compartilhar uma `AgentSession` entre múltiplos usuários | Histórico de um usuário vaza para outro |
136
- | Usar `InMemoryChatHistoryProvider` sem criar uma `AgentSession` por conversa | Sem `AgentSession` por conversa, o histórico é compartilhado entre todos os usuários; a isolation depende de `AgentSession` — sempre crie uma session por conversa via `agent.CreateSessionAsync()` |
137
- | Usar `AgentThread` (PersistentAgentsClient) sem necessidade | `AgentThread` requer hosted agent service; prefira `AgentSession` com direct model |
138
-
139
- ---
140
-
141
- ## Checklist (verifiable by morph-eval)
142
-
143
- - [ ] `AgentSession` usada somente em agentes conversacionais com UI de chat real
144
- - [ ] `InMemoryChatHistoryProvider` (ou equivalente) registrado em `ChatClientAgentOptions`
145
- - [ ] Uma `AgentSession` por conversa/usuário — nunca compartilhada
146
- - [ ] Estratégia de truncation definida (sliding window, token budget ou summarization)
147
- - [ ] Agentes one-shot (gerador, executor, classificador) **não** recebem session
148
-
149
- ---
150
-
151
- ## References
152
-
153
- - `ai-agents-setup` — packages e DI base
154
- - `ai-agents-sweet-spot` — decisão de quando adicionar estado ao agente
155
- - `ai-agents-middleware-patterns` (Onda 2) — pipeline de contexto e middleware
156
- - MAF Conversations docs: https://learn.microsoft.com/en-us/agent-framework/agents/conversations/
157
-
158
- ---
159
-
160
- *MORPH-SPEC by Polymorphism Tech — ai-agents/agent-session.md v1.0 (2026-05-19)*
1
+ # Agent Session — Conversation state and chat reducers
2
+
3
+ > **Scope:** stacks=["dotnet"]
4
+ > **Layer:** 2 (on-keyword)
5
+ > **Keywords:** agent session, chat history, conversation state, chat reducer, history truncation, AgentThread
6
+ > **Read by Claude in:** implement
7
+
8
+ **Verified against:** MAF 1.0 GA. Last-verified: 2026-05-19.
9
+
10
+ ---
11
+
12
+ ## Quando usar AgentSession
13
+
14
+ Use `AgentSession` quando o agente é **conversacional** — há uma UI de chat que mantém histórico entre turnos do usuário.
15
+
16
+ **Use AgentSession quando:**
17
+ - Existe uma interface de chat (web, mobile, CLI interativo)
18
+ - O agente precisa lembrar o que foi dito nos turnos anteriores da mesma conversa
19
+ - Há perguntas de follow-up ("e agora?", "altere o segundo ponto", "lembra do que disse sobre X?")
20
+
21
+ **NÃO use AgentSession quando:**
22
+ - O agente é one-shot (gerador, executor, classificador) — recebe uma entrada, devolve uma saída, fim
23
+ - Agentes stateless em pipeline multi-agent — cada chamada é independente
24
+ - Jobs de batch/background — não há conversa; histórico não faz sentido
25
+
26
+ > "Add Memory/Session because agents need state" é um anti-pattern de `sweet-spot.md`.
27
+ > Só adicione quando uma UI de chat real existe.
28
+
29
+ ---
30
+
31
+ ## A API
32
+
33
+ **Pacote:** `Microsoft.Agents.AI` (base; já requerido por `ai-agents-setup`).
34
+
35
+ **Tipos confirmados via context7:**
36
+ - `AgentSession` — container leve de estado de conversa; obtido via `agent.CreateSessionAsync()`
37
+ - `AgentThread` — equivalente para agentes persistentes (PersistentAgentsClient); use `agent.GetNewThread()`
38
+ - `ChatClientAgentOptions` — aceita `ChatHistoryProvider` e `AIContextProviders`
39
+ - `InMemoryChatHistoryProvider` — implementação embutida de histórico em memória
40
+ - `AgentResponse` — tipo retornado por `AIAgent.RunAsync` (non-generic); acesse o texto via `.Text`
41
+
42
+ ```csharp
43
+ // Construção do agente com histórico em memória
44
+ AIAgent agent = _modelRegistry.GetChatClient("text-default")
45
+ .AsAIAgent(new ChatClientAgentOptions
46
+ {
47
+ ChatOptions = new() { Instructions = "You are a helpful assistant." },
48
+ ChatHistoryProvider = new InMemoryChatHistoryProvider(),
49
+ });
50
+ ```
51
+
52
+ ---
53
+
54
+ ## Exemplo C# — agente conversacional com session persistente entre turnos
55
+
56
+ ```csharp
57
+ using Microsoft.Agents.AI;
58
+ using Microsoft.Extensions.AI;
59
+
60
+ // ── 1. Registrar o agente conversacional no DI ──
61
+ // Program.cs
62
+ builder.Services.AddSingleton<AIAgent>(sp =>
63
+ {
64
+ var registry = sp.GetRequiredService<ModelRegistry>();
65
+ return registry.GetChatClient("text-default")
66
+ .AsAIAgent(new ChatClientAgentOptions
67
+ {
68
+ ChatOptions = new() { Instructions = "You are a helpful customer support assistant." },
69
+ // InMemoryChatHistoryProvider: histórico vive em memória, por session.
70
+ // Seguro registrar como parte do singleton AIAgent: cada AgentSession criada via
71
+ // agent.CreateSessionAsync() isola o histórico de sua conversa — conversas distintas
72
+ // não compartilham estado. O provider em si é stateless; o estado fica na session.
73
+ // Para persistência entre restarts, substitua por um provider customizado (ex: DB).
74
+ ChatHistoryProvider = new InMemoryChatHistoryProvider(),
75
+ });
76
+ });
77
+
78
+ // ── 2. Criar uma session por conversa (ex: por conexão SignalR / por request de "start chat") ──
79
+ // ChatController.cs ou ChatHub.cs
80
+ public class ChatService(AIAgent _agent)
81
+ {
82
+ // Uma session por conversa ativa — armazene no escopo do usuário (cache, memória da conexão)
83
+ public async Task<AgentSession> StartConversationAsync()
84
+ => await _agent.CreateSessionAsync();
85
+
86
+ // Cada mensagem do usuário passa a mesma session
87
+ public async Task<string> SendMessageAsync(AgentSession session, string userMessage)
88
+ {
89
+ AgentResponse response = await _agent.RunAsync(userMessage, session);
90
+ return response.Text;
91
+ }
92
+ }
93
+
94
+ // ── 3. Uso no controller/hub ──
95
+ // Primeiro turno
96
+ AgentSession session = await chatService.StartConversationAsync();
97
+ string reply1 = await chatService.SendMessageAsync(session, "Meu pedido #1234 está atrasado.");
98
+ // reply1: "Vou verificar o pedido #1234 para você..."
99
+
100
+ // Segundo turno — o agente lembra do contexto anterior
101
+ string reply2 = await chatService.SendMessageAsync(session, "E quando foi despachado?");
102
+ // reply2: "O pedido #1234 foi despachado em..." ← contexto mantido pela session
103
+ ```
104
+
105
+ ---
106
+
107
+ ## History management
108
+
109
+ O histórico cresce a cada turno. Quando estoura o context window do modelo, as chamadas falham ou truncam silenciosamente.
110
+
111
+ ### Estratégias
112
+
113
+ | Estratégia | Quando usar | Como implementar |
114
+ |------------|-------------|------------------|
115
+ | **Sliding window** | Conversas longas com contexto recente suficiente | Limitar `InMemoryChatHistoryProvider` a N mensagens mais recentes |
116
+ | **Token budget** | Modelos com context window pequeno | Contar tokens acumulados; truncar quando ultrapassa threshold |
117
+ | **Summarization** | Histórico precisa de contexto antigo comprimido | Agente periódico que resume N turnos anteriores em uma mensagem única |
118
+
119
+ > **Custom history management:** Para o caso comum, `InMemoryChatHistoryProvider` cobre a
120
+ > necessidade de histórico em memória por sessão. Se o projeto exigir truncation customizada
121
+ > (ex: sliding window limitando a N mensagens mais recentes ou por token budget), o mecanismo
122
+ > de extensão correto — seja subclasse de `ChatHistoryProvider`, um `IChatReducer`, ou outro
123
+ > ponto de override — deve ser verificado contra a versão instalada de `Microsoft.Agents.AI`.
124
+ > Consulte a documentação MAF atual antes de implementar um provider customizado, pois a API
125
+ > exata de extensão não foi confirmada na versão GA e pode variar entre releases.
126
+
127
+ ---
128
+
129
+ ## Anti-patterns
130
+
131
+ | Anti-pattern | Problema |
132
+ |-------------|----------|
133
+ | Adicionar session em agente one-shot (gerador, executor) | Complexidade desnecessária; estado nunca é usado |
134
+ | Histórico ilimitado sem truncation | Context window estoura; custo aumenta linearmente com a conversa |
135
+ | Compartilhar uma `AgentSession` entre múltiplos usuários | Histórico de um usuário vaza para outro |
136
+ | Usar `InMemoryChatHistoryProvider` sem criar uma `AgentSession` por conversa | Sem `AgentSession` por conversa, o histórico é compartilhado entre todos os usuários; a isolation depende de `AgentSession` — sempre crie uma session por conversa via `agent.CreateSessionAsync()` |
137
+ | Usar `AgentThread` (PersistentAgentsClient) sem necessidade | `AgentThread` requer hosted agent service; prefira `AgentSession` com direct model |
138
+
139
+ ---
140
+
141
+ ## Checklist (verifiable by morph-eval)
142
+
143
+ - [ ] `AgentSession` usada somente em agentes conversacionais com UI de chat real
144
+ - [ ] `InMemoryChatHistoryProvider` (ou equivalente) registrado em `ChatClientAgentOptions`
145
+ - [ ] Uma `AgentSession` por conversa/usuário — nunca compartilhada
146
+ - [ ] Estratégia de truncation definida (sliding window, token budget ou summarization)
147
+ - [ ] Agentes one-shot (gerador, executor, classificador) **não** recebem session
148
+
149
+ ---
150
+
151
+ ## References
152
+
153
+ - `ai-agents-setup` — packages e DI base
154
+ - `ai-agents-sweet-spot` — decisão de quando adicionar estado ao agente
155
+ - `ai-agents-middleware-patterns` (Onda 2) — pipeline de contexto e middleware
156
+ - MAF Conversations docs: https://learn.microsoft.com/en-us/agent-framework/agents/conversations/
157
+
158
+ ---
159
+
160
+ *MORPH-SPEC by Polymorphism Tech — ai-agents/agent-session.md v1.0 (2026-05-19)*