@shanyucoder/flowgrid 0.1.5 → 0.1.9

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 (169) hide show
  1. package/README.md +1 -1
  2. package/adapters/laravel/registries/codegen.registry.json +9 -9
  3. package/bin/flowgrid.mjs +326 -115
  4. package/bin/lib/agent-mcp.mjs +4 -0
  5. package/bin/lib/agent-profiles.mjs +30 -6
  6. package/bin/lib/audit-run.mjs +1 -1
  7. package/bin/lib/cli-update.mjs +48 -8
  8. package/bin/lib/doctor.mjs +90 -3
  9. package/bin/lib/harness-overlay.mjs +12 -5
  10. package/bin/lib/harness-sync.mjs +17 -3
  11. package/bin/lib/init-adapters.mjs +75 -0
  12. package/bin/lib/init-scaffold.mjs +9 -0
  13. package/bin/lib/inject-consumer-scripts.mjs +115 -0
  14. package/bin/lib/merge-stack-config.mjs +89 -0
  15. package/bin/lib/project-gitignore.mjs +1 -0
  16. package/bin/lib/repo-maps-align.mjs +203 -0
  17. package/dist/graph/config/load-config.js +7 -2
  18. package/dist/graph/config/load-config.js.map +1 -1
  19. package/dist/graph/mcp/tools.js +1 -1
  20. package/dist/graph/mcp/tools.js.map +1 -1
  21. package/dist/graph/registry/load-registries.d.ts +1 -0
  22. package/dist/graph/registry/load-registries.js +14 -1
  23. package/dist/graph/registry/load-registries.js.map +1 -1
  24. package/engines/cases/render-cases.mjs +67 -5
  25. package/engines/docs/lib/qa-item.mjs +91 -0
  26. package/engines/docs/lib/render-api-summary-markdown.mjs +28 -0
  27. package/engines/docs/lib/render-bundle-markdown.mjs +77 -2
  28. package/engines/docs/lib/render-data-model-markdown.mjs +171 -0
  29. package/engines/docs/lib/render-design-tables.mjs +89 -7
  30. package/engines/docs/lib/render-qa-list.mjs +123 -25
  31. package/engines/docs/lib/render-template.mjs +6 -0
  32. package/engines/docs/render-docs.mjs +6 -2
  33. package/engines/docs/vitepress/config.ts +7 -7
  34. package/engines/docs/vitepress/surfaces-nav.mjs +45 -14
  35. package/engines/openapi/check-backend-spec.mjs +2 -2
  36. package/engines/openapi/lib/markdown-table.mjs +8 -0
  37. package/engines/openapi/lib/render-backend-spec-markdown.mjs +78 -0
  38. package/engines/registry-sync/be-capabilities-sync.mjs +118 -0
  39. package/engines/registry-sync/fe-design-sync.mjs +258 -0
  40. package/engines/registry-sync/run-registry-sync.mjs +107 -0
  41. package/engines/shared/e2e-output-layout.mjs +68 -0
  42. package/engines/shared/flowgrid-e2e-root.mjs +19 -0
  43. package/engines/shared/resolve-flowgrid-context.mjs +176 -0
  44. package/engines/spec/lib/audit-api-gaps.mjs +1 -1
  45. package/engines/spec/lib/audit-bundle-gaps.mjs +92 -3
  46. package/engines/spec/lib/audit-db-tables.mjs +529 -0
  47. package/engines/spec/lib/audit-e2e-coverage.mjs +88 -30
  48. package/engines/spec/lib/bundle-schema.mjs +4 -1
  49. package/engines/spec/lib/open-qa.mjs +71 -21
  50. package/engines/spec/split-bundle.mjs +11 -1
  51. package/engines/testcase/runners/generate-api.mjs +23 -23
  52. package/engines/testcase/runners/generate.mjs +19 -17
  53. package/engines/testcase/runners/lib/bootstrap-context.mjs +44 -0
  54. package/engines/testcase/runners/lib/write-files.mjs +37 -9
  55. package/harness/agents/antigravity/rules/antigravity-mcp.mdc +12 -0
  56. package/harness/agents/gemini/rules/gemini-mcp.mdc +11 -0
  57. package/harness/agents/gemini_antigravity/rules/antigravity-mcp.mdc +8 -6
  58. package/harness/be/skills/{grill-api → audit-api}/SKILL.md +8 -7
  59. package/harness/common/extracts/artifact-graph.md +2 -2
  60. package/harness/common/extracts/artifactgraph-phase-hooks.md +2 -2
  61. package/harness/common/extracts/docs-mark-detect.md +2 -2
  62. package/harness/common/extracts/entity-relationship.md +23 -0
  63. package/harness/common/rules/flowgrid-ux-common.mdc +3 -3
  64. package/harness/common/skills/configure-repo-maps/SKILL.md +4 -2
  65. package/harness/docs/extracts/agent-execution-protocol.md +3 -3
  66. package/harness/docs/extracts/api-codegen-readiness.md +34 -0
  67. package/harness/docs/extracts/api-codegen-tags.md +30 -0
  68. package/harness/docs/extracts/api-contract.md +43 -0
  69. package/harness/docs/extracts/api-spec-sync.md +35 -0
  70. package/harness/docs/extracts/artifactgraph-hooks-docs.md +1 -1
  71. package/harness/docs/extracts/call-external.md +16 -0
  72. package/harness/docs/extracts/common-scope.md +9 -10
  73. package/harness/docs/extracts/db-audit-wizard.md +45 -0
  74. package/harness/docs/extracts/derived-data.md +18 -0
  75. package/harness/docs/extracts/design-leaf-signoff.md +16 -0
  76. package/harness/docs/extracts/extract-registry.docs.json +11 -2
  77. package/harness/docs/extracts/qa-inbox.md +19 -10
  78. package/harness/docs/extracts/qa-team.md +32 -0
  79. package/harness/docs/extracts/spec-core.md +7 -3
  80. package/harness/docs/extracts/spec-evolution.md +21 -0
  81. package/harness/docs/extracts/spec-prd-lite.md +19 -0
  82. package/harness/docs/extracts/spec-requirement.md +6 -2
  83. package/harness/docs/extracts/spec-ssot-prep.md +25 -0
  84. package/harness/docs/extracts/tpl-module.md +12 -0
  85. package/harness/docs/extracts/verify-gate.md +33 -0
  86. package/harness/docs/extracts/wire-spec-feedback.md +31 -0
  87. package/harness/docs/rules/agent-compliance.mdc +1 -1
  88. package/harness/docs/rules/team-flow-spec.mdc +3 -4
  89. package/harness/docs/schemas/flowgrid-docs/qa-item.schema.json +65 -0
  90. package/harness/docs/skills/adopt/SKILL.md +2 -0
  91. package/harness/docs/skills/api/SKILL.md +4 -5
  92. package/harness/docs/skills/api-spec/SKILL.md +19 -6
  93. package/harness/docs/skills/api-update/SKILL.md +4 -4
  94. package/harness/docs/skills/architecture/SKILL.md +1 -1
  95. package/harness/docs/skills/business-process/SKILL.md +2 -0
  96. package/harness/docs/skills/common/SKILL.md +2 -2
  97. package/harness/docs/skills/common-spec/SKILL.md +10 -47
  98. package/harness/docs/skills/db-erd/SKILL.md +26 -0
  99. package/harness/docs/skills/grill/SKILL.md +28 -22
  100. package/harness/docs/skills/grill-api/SKILL.md +4 -6
  101. package/harness/docs/skills/grill-api-spec/SKILL.md +44 -24
  102. package/harness/docs/skills/grill-bqa/SKILL.md +28 -13
  103. package/harness/docs/skills/grill-common-spec/SKILL.md +10 -35
  104. package/harness/docs/skills/grill-dev/SKILL.md +8 -7
  105. package/harness/docs/skills/grill-docs/SKILL.md +11 -4
  106. package/harness/docs/skills/module/SKILL.md +3 -1
  107. package/harness/docs/skills/openapi/SKILL.md +2 -1
  108. package/harness/docs/skills/overview/SKILL.md +7 -1
  109. package/harness/docs/skills/qa-resolve/SKILL.md +13 -12
  110. package/harness/docs/skills/qa-review/SKILL.md +45 -0
  111. package/harness/docs/skills/spec/SKILL.md +43 -10
  112. package/harness/docs/skills/update-spec/SKILL.md +5 -2
  113. package/harness/fe/extracts/wire-audit-loop.md +72 -0
  114. package/harness/fe/extracts/wire-phase.md +45 -0
  115. package/harness/fe/rules/platform-design-vocabulary.mdc +1 -1
  116. package/harness/fe/rules/team-flow-prototype.mdc +8 -4
  117. package/harness/fe/skills/gen-common/SKILL.md +11 -84
  118. package/harness/fe/skills/grill-prototype/SKILL.md +51 -25
  119. package/harness/fe/skills/grill-test/SKILL.md +78 -20
  120. package/harness/fe/skills/grill-wire/SKILL.md +81 -0
  121. package/harness/fe/skills/prototype/SKILL.md +3 -2
  122. package/harness/fe/skills/wire/SKILL.md +8 -3
  123. package/harness/shared/AGENTS.md +3 -3
  124. package/harness/shared/SSOT_AGENT_PROTOCOL.md +3 -3
  125. package/harness/tests/extracts/grill-api-hook.md +69 -0
  126. package/harness/tests/extracts/grill-scenario-flow.md +39 -0
  127. package/harness/tests/extracts/grill-screen-tc.md +40 -0
  128. package/harness/tests/extracts/testcase-gen-cli.md +57 -0
  129. package/harness/tests/extracts/testcase-plan.md +29 -0
  130. package/harness/tests/extracts/tests-verify-gate.md +29 -0
  131. package/harness/tests/extracts/wire-test-handoff.md +37 -0
  132. package/harness/tests/skills/grill-testcase/SKILL.md +1 -0
  133. package/harness/tests/skills/test-api/SKILL.md +14 -6
  134. package/harness/tests/skills/testcase/SKILL.md +3 -1
  135. package/harness/tests/templates/TC.example-api.yaml +7 -1
  136. package/harness/tests/templates/TC.example.yaml +4 -1
  137. package/harness/tests/templates/tpl-testcase-plan.md +75 -0
  138. package/package.json +1 -1
  139. package/stacks/fastapi.json +1 -0
  140. package/stacks/laravel.json +1 -0
  141. package/stacks/nestjs.json +72 -0
  142. package/stacks/nextjs-nest.json +1 -0
  143. package/stacks/nuxt4-nest.json +1 -0
  144. package/templates/project-skeleton/architecture/03-business-process/FLOW-template.md +2 -0
  145. package/templates/project-skeleton/overview/index.md +68 -2
  146. package/templates/project-skeleton/overview/operational-areas/_template.md +37 -0
  147. package/templates/project-skeleton/qa/README.md +4 -8
  148. package/templates/project-skeleton/surfaces/common/data-model/index.md +10 -2
  149. package/templates/schemas/qa-item.schema.json +98 -0
  150. package/templates/shared/api-03-mock.stub.yaml +14 -0
  151. package/templates/shared/backend-api.bundle.yaml +3 -0
  152. package/templates/shared/backend-api.yaml +4 -0
  153. package/templates/shared/be-capabilities.registry.base.json +8 -0
  154. package/templates/shared/bundle-authoring.md +44 -7
  155. package/templates/shared/default-layout.ejs +131 -18
  156. package/templates/shared/design-spec.yaml +2 -3
  157. package/templates/shared/design.registry.base.json +38 -0
  158. package/templates/shared/feature.bundle.yaml +16 -9
  159. package/templates/shared/ir/generated/spec.md +281 -0
  160. package/templates/shared/ir-spec.yaml +1 -1
  161. package/templates/shared/qa-authoring.md +78 -0
  162. package/templates/shared/qa-item.yaml +35 -14
  163. package/templates/shared/tpl-api-contract.md +133 -0
  164. package/templates/shared/tpl-screen-data-model.md +76 -0
  165. package/templates/tests-skeleton/cases/README.md +4 -0
  166. package/templates/tests-skeleton/catalog/locale.yaml +9 -0
  167. package/templates/tests-skeleton/tpl-testcase-plan.md +9 -0
  168. package/harness/docs/skills/api-integration/SKILL.md +0 -110
  169. package/harness/docs/skills/grill-integration-spec/SKILL.md +0 -51
@@ -1,13 +1,20 @@
1
1
  import { lstat, mkdir, readFile, writeFile } from 'node:fs/promises'
2
2
  import path from 'node:path'
3
+ import {
4
+ DEFAULT_E2E_ROOT_REL,
5
+ E2E_ROOT_DIR_PARTS,
6
+ API_E2E_ROOT_DIR_PARTS,
7
+ } from '../../../shared/flowgrid-e2e-root.mjs'
3
8
 
4
- export const E2E_OUTPUT_ROOT = path.join('tests', 'e2e')
9
+ export const E2E_OUTPUT_ROOT = path.join(...E2E_ROOT_DIR_PARTS)
10
+ export const API_E2E_OUTPUT_ROOT = path.join(...API_E2E_ROOT_DIR_PARTS)
11
+ export { DEFAULT_E2E_ROOT_REL }
5
12
 
6
13
  /**
7
14
  * Preflight every output path before any write or dry-run result is produced.
8
15
  *
9
16
  * A target is accepted only when, lexically (without following symlinks), it
10
- * resolves strictly beneath `<root>/tests/e2e`. Rejected: absolute paths,
17
+ * resolves strictly beneath `<root>/tests/e2e` or `<root>/tests/api-e2e`. Rejected: absolute paths,
11
18
  * `..` traversal, targets outside `tests/e2e` (including sibling prefixes
12
19
  * such as `tests/e2e-evil`), existing symlink ancestors that could redirect
13
20
  * the write, and existing targets that are not regular files.
@@ -17,9 +24,28 @@ export const E2E_OUTPUT_ROOT = path.join('tests', 'e2e')
17
24
  * @param {string} root project root
18
25
  * @param {{ relativePath: string }[]} outputs
19
26
  */
20
- export async function preflightOutputPaths(root, outputs) {
27
+ function allowedAbsRoots(resolvedRoot, allowedRelRoots) {
28
+ const rels =
29
+ allowedRelRoots?.length
30
+ ? allowedRelRoots
31
+ : [E2E_OUTPUT_ROOT, API_E2E_OUTPUT_ROOT]
32
+ return rels.map((rel) => path.join(resolvedRoot, rel.replace(/\//g, path.sep)))
33
+ }
34
+
35
+ function isUnderCodegenTree(resolvedRoot, absolutePath, allowedRelRoots) {
36
+ return allowedAbsRoots(resolvedRoot, allowedRelRoots).some(
37
+ (base) => absolutePath === base || absolutePath.startsWith(base + path.sep),
38
+ )
39
+ }
40
+
41
+ /**
42
+ * @param {string} root
43
+ * @param {{ relativePath: string }[]} outputs
44
+ * @param {{ allowedRelRoots?: string[] }} [opts]
45
+ */
46
+ export async function preflightOutputPaths(root, outputs, opts = {}) {
21
47
  const resolvedRoot = path.resolve(root)
22
- const e2eRoot = path.join(resolvedRoot, E2E_OUTPUT_ROOT)
48
+ const allowedLabel = (opts.allowedRelRoots ?? [E2E_OUTPUT_ROOT, API_E2E_OUTPUT_ROOT]).join(', ')
23
49
  const errors = []
24
50
 
25
51
  for (const { relativePath } of outputs) {
@@ -31,22 +57,22 @@ export async function preflightOutputPaths(root, outputs) {
31
57
  }
32
58
  if (path.isAbsolute(relativePath)) {
33
59
  errors.push(
34
- `output ${label}: absolute paths are not allowed — use a path relative to the project root, under ${E2E_OUTPUT_ROOT}/`,
60
+ `output ${label}: absolute paths are not allowed — use a path relative to the project root, under: ${allowedLabel}`,
35
61
  )
36
62
  continue
37
63
  }
38
64
 
39
65
  if (relativePath.split(/[\\/]+/).includes('..')) {
40
66
  errors.push(
41
- `output ${label}: ".." traversal is not allowed — outputs must stay under ${E2E_OUTPUT_ROOT}/`,
67
+ `output ${label}: ".." traversal is not allowed — outputs must stay under: ${allowedLabel}`,
42
68
  )
43
69
  continue
44
70
  }
45
71
 
46
72
  const absolutePath = path.resolve(resolvedRoot, relativePath)
47
- if (!absolutePath.startsWith(e2eRoot + path.sep)) {
73
+ if (!isUnderCodegenTree(resolvedRoot, absolutePath, opts.allowedRelRoots)) {
48
74
  errors.push(
49
- `output ${label}: resolves outside ${E2E_OUTPUT_ROOT}/ — generated files must live beneath <projectRoot>/${E2E_OUTPUT_ROOT}` +
75
+ `output ${label}: resolves outside allowed codegen trees (${allowedLabel})` +
50
76
  ' (check module/testcase ids used to build output paths)',
51
77
  )
52
78
  continue
@@ -108,7 +134,9 @@ async function findUnsafePathComponent(resolvedRoot, absolutePath) {
108
134
  * @param {{ dryRun?: boolean, force?: boolean }} options
109
135
  */
110
136
  export async function writeOutputs(root, outputs, options = {}) {
111
- await preflightOutputPaths(root, outputs)
137
+ await preflightOutputPaths(root, outputs, {
138
+ allowedRelRoots: options.allowedRelRoots,
139
+ })
112
140
 
113
141
  const written = []
114
142
  const skipped = []
@@ -0,0 +1,12 @@
1
+ ---
2
+ description: Google Antigravity IDE — FlowGrid MCP (mcp_config.json under .antigravity)
3
+ alwaysApply: false
4
+ ---
5
+ # Antigravity IDE + FlowGrid
6
+
7
+ - Workspace harness: **`.antigravity/`** (Antigravity IDE hardcodes this path; it does **not** fall back to `.agents/`).
8
+ - MCP config: **`.antigravity/mcp_config.json`** (not `mcp.json`).
9
+ - Server name: `flowgrid` → `bin/flowgrid-mcp.mjs` from the FlowGrid package used at `flowgrid init`.
10
+ - Skills: **`.antigravity/skills/<name>/SKILL.md`**; rules: **`.antigravity/rules/`.
11
+ - Re-sync: `flowgrid harness sync --agent=antigravity`.
12
+ - **Gemini CLI / VS Code** use **`.agents/`** — select **Gemini (CLI / extension)** in init (`--agent=gemini`).
@@ -0,0 +1,11 @@
1
+ ---
2
+ description: Gemini CLI / extension — FlowGrid MCP (mcp.json under .agents)
3
+ alwaysApply: false
4
+ ---
5
+ # Gemini + FlowGrid
6
+
7
+ - Workspace harness: **`.agents/`** (open Agent Skills standard; Gemini CLI, VS Code Gemini extension, tools compatible with `.agents` / `.agent`).
8
+ - MCP config: **`.agents/mcp.json`** (server `flowgrid` → `bin/flowgrid-mcp.mjs` from the FlowGrid package used at `flowgrid init`).
9
+ - Skills: **`.agents/skills/<name>/SKILL.md`**; rules: **`.agents/rules/`.
10
+ - Re-sync: `flowgrid harness sync --agent=gemini`.
11
+ - **Antigravity IDE** uses a separate folder — select **Google Antigravity IDE** in init (`--agent=antigravity` → `.antigravity/`), not this profile.
@@ -1,10 +1,12 @@
1
1
  ---
2
- description: Antigravity — FlowGrid MCP wiring (mcp_config.json)
2
+ description: DEPRECATED — use gemini or antigravity agent profiles
3
3
  alwaysApply: false
4
4
  ---
5
- # Antigravity + FlowGrid
5
+ # Deprecated combined profile
6
6
 
7
- - MCP config file: `.agents/mcp_config.json` (not `mcp.json`).
8
- - Server name: `flowgrid` → `bin/flowgrid-mcp.mjs` from the FlowGrid package used at `flowgrid init`.
9
- - Skills live under `.agents/skills/`; rules under `.agents/rules/`.
10
- - Re-sync after config changes: `flowgrid harness sync --agent=gemini_antigravity`.
7
+ `gemini_antigravity` was split:
8
+
9
+ - **Gemini CLI / VS Code** → `flowgrid harness sync --agent=gemini` → `.agents/`
10
+ - **Antigravity IDE** → `flowgrid harness sync --agent=antigravity` → `.antigravity/`
11
+
12
+ Update `.flowgrid/config.json` `agents` and re-run init or harness sync.
@@ -1,10 +1,10 @@
1
1
  ---
2
- name: grill-api
3
- description: /grill-api — audit generated FastAPI/Laravel/Nest API before integration.
2
+ name: audit-api
3
+ description: /audit-api — audit generated BE routes/code against 01-backend-spec.yaml before wire.
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
7
- # /grill-api
7
+ # /audit-api — BE implementation vs contract
8
8
 
9
9
  Run after `npm run codegen:api:dry` / `flowgrid api-gen:dry` and after implementation.
10
10
 
@@ -13,7 +13,7 @@ Run after `npm run codegen:api:dry` / `flowgrid api-gen:dry` and after implement
13
13
  ## Target / ID Resolution Rule
14
14
 
15
15
  - User prompt MAY specify a function ID, API slug, or short name (e.g. `API-AUTH-001`, `login`, `CMP-ADM-009`).
16
- - Agent MUST resolve **`…/api/<seq>/01-backend-spec.yaml`** via `FLOWGRID_DOCS_ROOT` or `flowgrid_docs_route` (screen leaf `CMP-*/<NN…>/api/<seq>/`, or `common/yaml/<slug>/`, or `integrations/…/api/<seq>/`).
16
+ - Agent MUST resolve **`…/api/<seq>/01-backend-spec.yaml`** via `FLOWGRID_DOCS_ROOT` or `flowgrid_docs_route` (screen leaf `CMP-*/<NN…>/api/<seq>/`, or `common/yaml/<slug>/`, or external-channel surface `…/api/<seq>/`).
17
17
  - **Read the entire `01-backend-spec.yaml`**. Do **not** use `ir/design.yaml` or `ir/spec.yaml` as BE contract.
18
18
  - Compare generated routes/code against that 01 file. Missing 01 → STOP, hand off to docs `/grill-api-spec`.
19
19
  - Do NOT demand full filesystem paths from the user if an ID is given.
@@ -36,6 +36,8 @@ Check:
36
36
  - Writes are transaction-safe; async retries are idempotent.
37
37
  - Generated placeholders are replaced before ship.
38
38
 
39
+ **CLI (lượng):** `flowgrid audit api` on `01`; when portal bundle exists → `flowgrid audit fe-be` on sibling `*.bundle.yaml`.
40
+
39
41
  ## Accelerators (optional)
40
42
 
41
43
  ```text
@@ -48,9 +50,8 @@ else: targeted repository search
48
50
  architecture IDs / C4 → bộ docs (FLOWGRID_DOCS_ROOT), never CodeGraph
49
51
  ```
50
52
 
51
- Missing accelerators never block the grill. Complete each scoped model or
52
- targeted-local fallback first, then follow
53
- the remainder of this skill.
53
+ Missing accelerators never block the audit. Complete each scoped model or
54
+ targeted-local fallback first, then follow the remainder of this skill.
54
55
 
55
56
  ## Translation Rule (i18n)
56
57
  Always wrap static text with native framework i18n helpers (e.g. `__('key')`, `_localizer["key"]`, `i18n.t('key')`).
@@ -17,7 +17,7 @@ Path root: `base-docs Code / `--id``
17
17
  | /test | `*.test.yaml`, ir/spec testIds | legacy-api-migration |
18
18
  | /unit | ir/spec + `{function}/generated/unit.manifest.json` | legacy/* |
19
19
  | /model | ir/spec entities + project-config | trace full |
20
- | /grill-api | legacy/api-migration | models/ |
21
- | update-spec-legacy | trace slice + bundle.legacy patch | macro legacy read |
20
+ | /audit-api | legacy/api-migration | models/ |
21
+ | /update-spec | trace slice + bundle.legacy patch | macro legacy read (dùng `/legacy /spec` khi re-adopt) |
22
22
 
23
23
  Generated output: `{function}/generated/` (HANDOFF, manifests) — cạnh bundle, không trong `ir/`.
@@ -28,7 +28,7 @@ Cloud **không** viết registry. Promote = docs `DESIGN-REGISTRY-PROMOTION` / `
28
28
 
29
29
  ## Shared protocol (every artifact skill)
30
30
 
31
- 1. Run `artifactgraph init` once in the current product repo, then use
31
+ 1. Run `flowgrid init` once in the current product repo, then use
32
32
  `artifactgraph_status`; project-local MCP is the default.
33
33
  2. **Local:** `artifactgraph_analyze` or `artifactgraph_grill_check`; after legacy also **`artifactgraph_parity_check`**.
34
34
  3. **API reuse check (BE/docs):** Run `artifactgraph_api_reuse_check` before creating
@@ -50,7 +50,7 @@ Cloud **không** viết registry. Promote = docs `DESIGN-REGISTRY-PROMOTION` / `
50
50
  - Cloud: only unknown domain rules in `cloudPromptSlice`.
51
51
  - **Không** `portal:gen` app ở phase này (trừ khi skill nói rõ dry gate).
52
52
 
53
- ### `/api-spec` · `/api-integration-spec`
53
+ ### `/api-spec`
54
54
 
55
55
  - **Pre-flight:** `artifactgraph_api_reuse_check({ path, method })` trước khi viết spec.
56
56
  - `found: true` → add `#reuse-api` vào spec; không cần tạo spec mới.
@@ -8,7 +8,7 @@
8
8
  |--------|----------------|------------|
9
9
  | Endpoint mô tả payment/webhook/MES/ERP | `#call-external` | A local B `#call-external` C defer |
10
10
  | 2 entity độc lập, 1 flow sync | `#cross-entity-service` | A relationship B cross-entity C split APIs |
11
- | Field/response key không có trên `ir/spec.yaml` entities | `#derived-data` | A add to contract B `#derived-data` C remove |
11
+ | Field/response key không có trên `ir/design.yaml` (`entities` / `sections[].db`) hoặc `01-backend-spec.yaml` `modules[].entities` | `#derived-data` | A add to contract B `#derived-data` C remove |
12
12
  | Tag có nhưng thiếu block (`externalCalls`, `services`, `derivedData`) | validation fail | Fix via `/docs-mark` |
13
13
  | `commonRefs` trỏ registry `planned` | HANDOFF debt | Implement or defer in `openQuestions` |
14
14
 
@@ -42,7 +42,7 @@ If member chooses **B** → run `/docs-mark` in the same session.
42
42
  | `artifactgraph_api_reuse_check` finds existing route for same path+method | `#reuse-api` | Agent adds `#reuse-api` to spec (no gate) |
43
43
  | Endpoint calls payment/webhook/OAuth/SMS/MES/ERP system | `#call-external` | A local B `#call-external` C defer |
44
44
  | 2 bounded-context entities in single synchronous flow | `#cross-service` / `#cross-entity-service` | A single service B cross-service C split APIs |
45
- | Response field không có trên `ir/spec.yaml` entities | `#derived-data` | A add to entity B `#derived-data` C remove |
45
+ | Response field không có trên `01` entity fields / `ir/design` `db.field` | `#derived-data` | A add to `01` B `#derived-data` C remove |
46
46
  | `DUPLICATE_API_ROUTE` gap in grill_check output | add `#reuse-api` | Agent adds `#reuse-api` to current spec |
47
47
 
48
48
  **Rule:** If 2 specs define the exact same URI path+method without `#reuse-api`, ArtifactGraph emits `DUPLICATE_API_ROUTE` gap (`severity: warn`, `draftTags: ['#reuse-api']`). Agent adds the tag to resolve — no member gate needed.
@@ -0,0 +1,23 @@
1
+ # Entity & relationships — SSOT map
2
+
3
+ Dùng khi grill-api-spec / codegen handoff `#manual-action:` (Eloquent relationships, joins).
4
+
5
+ ## Ba nguồn (không trùng vai)
6
+
7
+ | Layer | Artifact | Nội dung |
8
+ |-------|----------|----------|
9
+ | Phase 0 | `<LCA>/common/db-erd.md` | ER tổng, ownership, cardinality — skill `/db-erd` |
10
+ | Design | `ir/design.yaml` | `entities`, `relationships`, `sections[].db` (column binding) |
11
+ | BE contract | `api/<seq>/01-backend-spec.yaml` | `modules[].entities[].fields`, quan hệ codegen |
12
+
13
+ Workflow: [architecture-data.md](../../../docs/workflows/architecture-data.md) (repo hub).
14
+
15
+ ## Quy tắc sync
16
+
17
+ - Thêm bảng/entity **mới** → cập nhật **db-erd** (Phase 0) trước khi mở rộng `01`.
18
+ - Quan hệ runtime (belongsTo, hasMany, …) → khớp cardinality trong ERD; chi tiết ORM trong Action theo `01` + ERD.
19
+ - Field chỉ search/compute → `#derived-data` (`common/data-model/derived-data.md`), không fake FK trên ERD.
20
+
21
+ ## Handoff codegen
22
+
23
+ Khi tag `#manual-action:relationships`: đọc ERD + `01` module entity list; implement relationship trên model/Action — không invent entity name lệch ERD.
@@ -5,7 +5,7 @@ alwaysApply: true
5
5
 
6
6
  # UX proposals (global)
7
7
 
8
- **DSL and bundle SSOT:** `/spec`, `/update-spec`, `design.registry.json`, `gen-common`. Do not replace spec authoring with the checklist extract.
8
+ **DSL and bundle SSOT:** `/spec`, `/update-spec`, `design.registry.json`, FE base components. Do not replace spec authoring with the checklist extract.
9
9
 
10
10
  ## When this applies
11
11
 
@@ -16,8 +16,8 @@ Prompt analysis, UI proposals, affordance review. **Primary:** `/spec` per-zone
16
16
  1. Map DSL/registry first (`#shell:`, `#pattern:`, `#ui:`, `#widget:`, generated CMN).
17
17
  2. On match → codegen/wire only; no redundant YAML/spec.
18
18
  3. Unmapped, missing DSL, or UI not recognized as a pattern → read **`.cursor/extracts/ux-common-patterns.md`**; apply matching **Recognize** / **Propose** sections.
19
- 4. **`flowgrid audit spec`** — patch `UX_*` gaps in bundle; `CONFIRM_UX_*` → `AskQuestion` using audit `(Recommended)` options.
20
- 5. Stable cross-project pattern → `gen-common`; never hand-duplicate common IR.
19
+ 4. **`flowgrid audit spec`** — patch `UX_*` gaps; `CONFIRM_UX_*` → `AskQuestion`. **`CONFIRM_DB_*`** (`category: db`) → same wizard rules — see `db-audit-wizard.md`.
20
+ 5. Stable cross-project pattern → already in FE base or [custom-base](../../../docs/workflows/custom-base.md); never author `common/yaml` on the hub.
21
21
 
22
22
  | Situation | Action |
23
23
  |-----------|--------|
@@ -54,5 +54,7 @@ legacy ERP at D:\legacy\erp, key legacy-erp
54
54
 
55
55
  ## After Write
56
56
 
57
- 1. Run `platform-dna codegraph:wire` (when utilizing Cursor + CodeGraph).
58
- 2. For checkouts lacking `.codegraph/`: `cd <root> && codegraph init`.
57
+ 1. Compare with `.flowgrid/config.json` (init SSOT): `flowgrid repo-maps check`.
58
+ 2. If paths conflict with init/harness MCP: `flowgrid repo-maps align` (member chốt từng hub `docs` / `tests`).
59
+ 3. One-way refresh from config: `flowgrid repo-maps sync --from-config` then `flowgrid harness sync`.
60
+ 4. Optional CodeGraph: `platform-dna codegraph:wire` · `codegraph init` per checkout.
@@ -17,15 +17,15 @@ surfaces/<surface>/CMP-*/<slug>/ # no modules/ segment
17
17
 
18
18
  1. **PRE-FLIGHT:** First action = `{{FLOWGRID_READ_TOOL}}` / read target `SKILL.md`. Never memory.
19
19
  4. **NO RAM CACHING:** Durable results → disk immediately. Prior file = next input.
20
- 5. **ZERO BUSINESS HALLUCINATION:** Data only from User prompt or ArtifactGraph. Gaps → AskQuestion (MUST include "Log as Tech Debt" option); if member selects "Log as Tech Debt" → `qa/open/QA-<page-id>-NNNN.yaml` + `#missing_info QA-…`. No invented business fields.
20
+ 5. **ZERO BUSINESS HALLUCINATION:** Data only from User prompt or ArtifactGraph. Gaps → AskQuestion (MUST include "Log as Tech Debt" option); if member selects "Log as Tech Debt" → `qa/<SHORT>_NNNN.yaml` + `#missing_info QA-…`. No invented business fields.
21
21
  6. **GRILL HARD GATE:** AG re-check → micro-scope → propose → **STOP for Confirm** before product SSOT write.
22
- 7. **HUMAN DSL:** Common/DSL only via `/common`, `/common-spec`, `/docs-mark`, or grill Confirm. `/spec` consumes only.
22
+ 7. **HUMAN DSL:** Common/DSL only via `/common`, `/docs-mark`, custom-base, or grill Confirm. `/spec` consumes only (no `common/yaml`).
23
23
 
24
24
  ## Order
25
25
 
26
26
  ```text
27
27
  {{FLOWGRID_READ_TOOL}} SKILL.md
28
28
  → durable writes immediately (No RAM)
29
- → AskQuestion or qa/open + grill Confirm before SSOT fill
29
+ → AskQuestion or qa + grill Confirm before SSOT fill
30
30
  → common/DSL only when human-gated
31
31
  ```
@@ -0,0 +1,34 @@
1
+ # API codegen readiness (`/grill-api-spec`)
2
+
3
+ Stop handoff to `api-gen` until `01` passes below.
4
+
5
+ ## Required on `01`
6
+
7
+ | Field / block | Notes |
8
+ |---------------|--------|
9
+ | `codegen.profile` | e.g. `crud-standard`, `list`, `command-stub` — see registry |
10
+ | `codegen.module` / `codegen.entity` | Match `modules[].entities[]` primary |
11
+ | `api.endpoints[].action` | Aligns with path suffix (`search`, `create`, …) |
12
+ | `approval.status` | Team policy: `approved` before production `api-gen` |
13
+
14
+ ## Gates (docs hub cwd)
15
+
16
+ ```text
17
+ flowgrid audit api <01>
18
+ flowgrid audit fe-be <bundle.yaml> # portal-backed only
19
+ flowgrid api:check --spec <01>
20
+ flowgrid openapi_gen --spec <01>
21
+ flowgrid openapi_render
22
+ flowgrid render
23
+ ```
24
+
25
+ ## `/api-spec` vs `/grill-api-spec`
26
+
27
+ - `/api-spec`: domain tags `#err:*`, `#call-external`, URI rules — **no** `#gen:*` / full codegen block.
28
+ - `/grill-api-spec`: adds `#gen:*`, `approval`, codegen completeness.
29
+
30
+ ## Still missing after grill?
31
+
32
+ `#tech-debt:QA-*` + `qa/` — or `/qa-resolve`. Do not ship silent gaps.
33
+
34
+ Registry: BE checkout `registries/codegen.registry.json` (after `registry:sync`).
@@ -0,0 +1,30 @@
1
+ # API `#gen:*` tags (grill-api-spec)
2
+
3
+ Apply on **`01-backend-spec.yaml`** (endpoint `tags[]` or root `tags` per registry). `/api-update` does **not** add `#gen:*` — grill only.
4
+
5
+ ## Common tags (Laravel registry mirror)
6
+
7
+ | Tag | Typical use |
8
+ |-----|-------------|
9
+ | `#gen:module` | Scaffold module shell |
10
+ | `#gen:crud` | CRUD controller/service bundle |
11
+ | `#gen:model-tenant` / `#gen:model-platform` | Entity model scope |
12
+ | `#gen:test-module` | Module-level test stub |
13
+ | `#gen:test-unit` | Unit tests per endpoint policy |
14
+ | `#gen:select-items` | Dropdown/list helper endpoints |
15
+ | `#gen:action-<name>` | Custom action pipeline |
16
+
17
+ ## Domain (non-gen)
18
+
19
+ | Tag | When |
20
+ |-----|------|
21
+ | `#call-external` | Outbound HTTP + `externalCalls[]` |
22
+ | `#cross-entity-service` | `services[]` multi-aggregate |
23
+ | `#manual-service` | Hand-written service block |
24
+ | `#err:*` | Error storming (also on `errorStorming`) |
25
+
26
+ ## Verify
27
+
28
+ After tagging: `api-gen:dry -- --spec <01>` on BE repo with `FLOWGRID_DOCS_ROOT` set.
29
+
30
+ Do not invent tags absent from `codegen.registry.json` without member approval.
@@ -0,0 +1,43 @@
1
+ # API contract — đọc/ghi (agent digest)
2
+
3
+ Hub SSOT: `templates/shared/tpl-api-contract.md` (sau init: `.flowgrid/templates/tpl-api-contract.md`).
4
+
5
+ ## SSOT
6
+
7
+ | Ghi | Đọc review |
8
+ |-----|------------|
9
+ | `api/<seq>/01-backend-spec.yaml` | `ir/generated/api.md` (sau `flowgrid render`) |
10
+ | `02-openapi.yaml` | Gen only — sửa `01` + `openapi_gen` |
11
+ | `ir/design.yaml` `apiRefs` | Portal FE — **không** input BE codegen |
12
+
13
+ Mẫu `01`: `.flowgrid/templates/backend-api.yaml`. **Không** dùng `backend-api.bundle.yaml` cho contract mới.
14
+
15
+ ## Trio
16
+
17
+ ```text
18
+ api/<seq>/01-backend-spec.yaml
19
+ api/<seq>/02-openapi.yaml
20
+ api/<seq>/03-mock.yaml # optional — stub: api-03-mock.stub.yaml
21
+ ```
22
+
23
+ ## OpenAPI chain (sau mỗi sửa `01`)
24
+
25
+ ```text
26
+ flowgrid api:check --spec …/01
27
+ flowgrid openapi_gen --spec …/01
28
+ flowgrid openapi_render
29
+ flowgrid render
30
+ ```
31
+
32
+ **Forbidden:** `flowgrid check` on `01`; hand-edit `02` as SSOT; `nestjs --openapi` on docs hub.
33
+
34
+ ## Portal vs BE-only
35
+
36
+ - `base` ≠ `none` → read `ir/design.yaml` for `/api-spec`; `audit fe-be` + `audit api`.
37
+ - `base: none` → **`01` only** for contract; `audit api` only.
38
+
39
+ ## Reuse
40
+
41
+ `#reuse-api` + `reuseFrom` on design action — **no** new `api/<seq>/` folder.
42
+
43
+ Workflow hub: `docs/workflows/backend.md`.
@@ -0,0 +1,35 @@
1
+ # API spec sync — portal ↔ `01`
2
+
3
+ Dùng với `/api-spec`, `/api-update`, `/grill-api-spec`.
4
+
5
+ ## `/api-update` modes
6
+
7
+ | Mode | Trigger | Allowed |
8
+ |------|---------|---------|
9
+ | `portal-sync` (default) | Portal đổi `ir/design.yaml` | Diff design → patch `01` (+ `03-mock.yaml`); regen `02` |
10
+ | `be-only` | `--be-only` | `beOnlyRequirements`, internal validation — **no** breaking FE contract |
11
+
12
+ ## Portal-sync steps
13
+
14
+ 1. Read full `ir/design.yaml` — `apiRefs`, `#reuse-api`, `reuseFrom` (ignore projected `design.api` as SSOT).
15
+ 2. Diff vs `01-backend-spec.yaml` (endpoints, DTO, errors, entities).
16
+ 3. Patch `01` (+ mock if samples change); **never** hand-edit `02`.
17
+ 4. `api:check` → `openapi_gen` → bump `feature.version` + `changeLog[]`.
18
+ 5. `flowgrid render` → refresh `ir/generated/api.md`.
19
+ 6. Handoff: `/grill-api-spec` (codegen tags, `approval`).
20
+
21
+ ## `#reuse-api`
22
+
23
+ Action marked reuse → **do not** create duplicate trio; pointer must resolve to existing `01`.
24
+
25
+ ## Common APIs
26
+
27
+ Path: `…/common/yaml/<slug>/01-backend-spec.yaml` — same trio rules, scan before new endpoint on leaf.
28
+
29
+ ## Missing facts
30
+
31
+ AskQuestion (Recommended / Other / Tech Debt) → `qa/*` — **no** `openQuestions` in YAML.
32
+
33
+ ## Field rename guard
34
+
35
+ **Forbidden:** rename API fields only to match FE convenience without member decision.
@@ -3,7 +3,7 @@
3
3
  - Treat this docs repo as the canonical full registry/parity hub (`surfaces/...`).
4
4
  - Use path hints from `registries/docs-index.json` when available.
5
5
  - Use local vocabulary suggestions for specs and documentation marks.
6
- - Before `/api-spec`, `/api-integration-spec`, `/grill-with-docs`, or `/bqa-grill-docs`,
6
+ - Before `/api-spec`, `/grill-with-docs`, or `/bqa-grill-docs`,
7
7
  run `artifactgraph_api_reuse_check` to validate route uniqueness across product surfaces.
8
8
  Docs hub is SSOT — if a route already exists in a sibling surface, apply `#reuse-api`
9
9
  or document the divergence in `openQuestions`.
@@ -0,0 +1,16 @@
1
+ # `#call-external` — outbound integrations
2
+
3
+ Hashtag only (via `/api-spec`, `/grill-api-spec`, `/api-update`) — **not** a standalone slash skill.
4
+
5
+ ## On `01` only
6
+
7
+ - Add `externalCalls[]` entry: `id`, `provider`, `direction`, `trigger`, `timeoutMs`, `retry`, `idempotency`, `secrets` refs.
8
+ - Tag endpoint: `#call-external` in `tags[]` or `errorStorming`.
9
+
10
+ ## Rules
11
+
12
+ - Never edit `ir/design.yaml` for external contract detail.
13
+ - No invented secrets — AskQuestion or `qa/`.
14
+ - Grill: timeout/retry/idempotency must be explicit before `api-gen`.
15
+
16
+ Hub: `docs/references/skills/call-external.md`.
@@ -1,6 +1,8 @@
1
1
  # Common + FLOW placement (lowest shared folder)
2
2
 
3
- Agents MUST pick **one** `common/` using the **lowest folder that every consumer already shares**. Do not invent extra `common/` trees. `/spec` only **consumes**; create/update common only via `/common`, `/common-spec`, or `/module … common` after the user named the scope.
3
+ Agents MUST pick **one** `common/` using the **lowest folder that every consumer already shares**. Do not invent extra `common/` trees. `/spec` only **consumes**; create/update common Markdown only via `/common` (or `/module … common`) after the user named the scope.
4
+
5
+ **No `common/yaml` on new hubs** — UI patterns live in the FE base + `flowgrid-ux-common.mdc`; new codegen templates → custom-base (`build-template-code`).
4
6
 
5
7
  Numeric function folders stay numeric (`01/02/03/`). The only non-numeric directory names under a `CMP-*` are `common/` and the `CMP-*` id itself.
6
8
 
@@ -23,10 +25,11 @@ Inside every `common/`:
23
25
  ```text
24
26
  common/
25
27
  patterns/ ← /common Markdown (BA/QA rules)
26
- yaml/<slug>/ ← /common-spec *.bundle.yaml
27
28
  processes/ ← module/cluster FLOW-*.md (not architecture catalog)
28
29
  ```
29
30
 
31
+ Optional: `data-model/`, `integrations/`, `db-erd.md`, `cross-service.md` at the same LCA (see skills `/db-erd`, `/cross-service`).
32
+
30
33
  ## 2. Ambiguous scope
31
34
 
32
35
  If the prompt does not name consumers, **stop and ask** (propose the LCA from the table). Do not default to `surfaces/common` or to a random function folder.
@@ -35,12 +38,7 @@ If the same pattern already exists at a **narrower** `common/`, **reuse it** (re
35
38
 
36
39
  ## 3. Consume order (`/spec`, `/grill-*`, `/api-spec`)
37
40
 
38
- From the function folder, walk **up** and use the **nearest** hit. Do not skip a module `common/` to copy into surface `common/`.
39
-
40
- 1. `…/<CMP>/<cluster…>/common/yaml/` (nearest ancestor `common/`)
41
- 2. `…/<CMP>/common/yaml/`
42
- 3. `surfaces/<surface>/common/yaml/`
43
- 4. `surfaces/common/yaml/`
41
+ From the function folder, walk **up** and read the **nearest** `common/patterns/*.md` (and FLOW under `processes/` when relevant). Do not author duplicate YAML CMN bundles.
44
42
 
45
43
  Same walk for `patterns/` Markdown.
46
44
 
@@ -60,6 +58,7 @@ Do **not** drop `FLOW-*.md` beside a single `W-*` bundle. Do **not** write modul
60
58
  ## 5. Forbidden
61
59
 
62
60
  - Creating `common/` from `/spec`
63
- - Textual slugs in the path (`auth/`, `cluster-name/`) except `common/` and `yaml/<bundle-slug>/`
64
- - Duplicate copies of the same bundle at two LCA levels
61
+ - `common/yaml/`, `/common-spec`, `/gen-common`, `/grill-common-spec` on new hubs
62
+ - Textual slugs in the path (`auth/`, `cluster-name/`) except `common/` and bundle slugs under function leaves
63
+ - Duplicate copies of the same rule at two LCA levels
65
64
  - `Surfaces/Common` mixed case when the hub uses `surfaces/`
@@ -0,0 +1,45 @@
1
+ # DB audit — grill /spec AskQuestion wizard
2
+
3
+ > Source: `flowgrid audit spec` → `confirms[]` where `category: db` and codes `CONFIRM_DB_*`.
4
+ > Agent **MUST NOT** silently pick DB mappings — run wizard like `CONFIRM_UX_*`.
5
+
6
+ ## When
7
+
8
+ - `/spec` after audit (existing bundle or mid-authoring)
9
+ - `/grill-bqa` Step B, `/grill-dev`, `/grill-docs` after `audit spec` re-run
10
+ - Law 2: ≤5 `CONFIRM_DB_*` in one chat batch → one question at a time; ≥10 total gaps+confirms → Plan Mode
11
+
12
+ ## Member prompt template
13
+
14
+ ```text
15
+ [GRILL-DB] {short finding}
16
+ Path: {confirm.path}
17
+ Question: {confirm.question}
18
+
19
+ Chọn (khớp option audit):
20
+ A) {options[0]} ← (Recommended) when defaultRecommend === 0
21
+ B) {options[1]}
22
+ C) Log as Tech Debt (Pending) — or option[2] if audit lists it
23
+ ```
24
+
25
+ After answer → patch bundle (`spec.entities`, `design.sections[].db`, `design.dataModel`, or handoff `/api-update` for `01`) → **re-run** `flowgrid audit spec`.
26
+
27
+ ## Code → action map
28
+
29
+ | Code | Member chọn (Recommended) thường là |
30
+ |------|-------------------------------------|
31
+ | `CONFIRM_DB_SPEC_ENTITIES` | Điền `spec.entities[]` khớp ERD |
32
+ | `CONFIRM_DB_MULTI_TABLE_OVERVIEW` | `design.dataModel.tables[]` per table |
33
+ | `CONFIRM_DB_MULTI_TABLE_ENTITIES` | Bổ sung entity cho bảng phụ |
34
+ | `CONFIRM_DB_REQUIRED_MAPPING` | Thêm `db.schema` + `db.field` |
35
+ | `CONFIRM_DB_PARTIAL_BINDING` | Hoàn thiện schema+field hoặc `#derived-data` |
36
+ | `CONFIRM_DB_BIND_CONFLICT` | Tách `bind.field` hoặc DTO nested trên 01 |
37
+ | `CONFIRM_DB_LIST_COLUMN_STORAGE` | `columns[].db` hoặc `#derived-data` |
38
+ | `CONFIRM_DB_BE_TABLE_DRIFT` / `CONFIRM_DB_BE_FIELD_DRIFT` | `/api-update` hoặc sửa design `db` |
39
+ | `CONFIRM_DB_BE_SPEC_MISSING` | Author `01` trước grill-dev |
40
+
41
+ ## Review artifact
42
+
43
+ Sau split: `ir/generated/data-model.md` (multi-table). BA đọc cùng wizard — không thay `confirms[]`.
44
+
45
+ Extracts: `architecture-data.md` (workflow) · `tpl-screen-data-model.md` (author template).
@@ -0,0 +1,18 @@
1
+ # `#derived-data` — API & design
2
+
3
+ Fields **computed / search-only** — not persisted FK on ERD.
4
+
5
+ ## Where to mark
6
+
7
+ | Layer | How |
8
+ |-------|-----|
9
+ | Design | List column / bind without `db.field`; tag `#derived-data` on item/column |
10
+ | BE `01` | Field in response/DTO without table column — document in endpoint purpose or `technicalMarks` |
11
+
12
+ Prose: `surfaces/common/data-model/derived-data.md` (skeleton) · bundle [tpl-screen-data-model.md](../../../templates/shared/tpl-screen-data-model.md).
13
+
14
+ ## Audit
15
+
16
+ `flowgrid audit spec` may suggest `#derived-data` when column has no `db` mapping.
17
+
18
+ Do not add fake `modules.entities.fields` for pure UI computed values unless API truly returns them.
@@ -0,0 +1,16 @@
1
+ # Design leaf sign-off (voluntary)
2
+
3
+ Hub SSOT: `docs/workflows/design-leaf-signoff.md` — **không** engine gate.
4
+
5
+ ## Rubric 6 mục (lead/BA)
6
+
7
+ 1. `flowgrid audit spec <bundle> --type <profile>` — `gaps[]` xử lý; `confirms[]` chốt hoặc `qa`.
8
+ 2. VitePress `ir/generated/spec.md` (+ `data-model.md`) — stories, list columns, AC không placeholder.
9
+ 3. Spot 2–3 scenario ↔ `design.actions` / validation messages VI.
10
+ 4. `api/.../01-backend-spec.yaml` ↔ `ir/design.yaml` apiRef; `audit fe-be` nếu có BE.
11
+ 5. `grillStatus.dev: done` (theo flow); `gen:dry` pass; `bundle.gen` đầy đủ.
12
+ 6. `qa` rỗng hoặc debt đã accept.
13
+
14
+ Optional: **Data model** — `db-erd` LCA + `design.sections[].db` / `spec.entities` (xem hub `architecture-data.md`). `/grill-prototype` SSOT issues; `registry:sync` trên FE standard base.
15
+
16
+ Ghi nhận: `Design sign-off: <page-id> | reviewer | date | 6/6` (PR/chat — không bắt buộc field YAML).