@shanyucoder/flowgrid 0.1.11 → 0.1.13

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 (83) hide show
  1. package/adapters/shared/resolve-hub-id.mjs +5 -1
  2. package/dist/docs/mcp/tools.js +59 -6
  3. package/dist/docs/mcp/tools.js.map +1 -1
  4. package/dist/docs/scan/screen-to-flows.d.ts +3 -0
  5. package/dist/docs/scan/screen-to-flows.js +18 -0
  6. package/dist/docs/scan/screen-to-flows.js.map +1 -0
  7. package/engines/docs/lib/render-bundle-markdown.mjs +19 -0
  8. package/engines/docs/lib/render-design-markdown.mjs +56 -0
  9. package/engines/docs/lib/screen-to-flows-index.mjs +121 -0
  10. package/engines/docs/vitepress/surfaces-nav.mjs +7 -0
  11. package/engines/spec/lib/audit-bundle-gaps.mjs +15 -3
  12. package/engines/spec/lib/audit-interaction-cases.mjs +186 -0
  13. package/engines/spec/lib/bundle-ir.mjs +7 -0
  14. package/engines/spec/lib/bundle-schema.mjs +1 -0
  15. package/engines/spec/lib/interaction-cases.mjs +46 -0
  16. package/engines/spec/split-bundle.mjs +1 -1
  17. package/harness/be/adapters/dotnet-integration/skills/framework-rules-be/SKILL.md +2 -2
  18. package/harness/be/adapters/fastapi/skills/framework-rules-be/SKILL.md +3 -3
  19. package/harness/be/adapters/laravel/skills/framework-rules-be/SKILL.md +3 -3
  20. package/harness/be/skills/api/SKILL.md +4 -4
  21. package/harness/be/skills/api-unit/SKILL.md +4 -4
  22. package/harness/be/skills/audit-api/SKILL.md +3 -3
  23. package/harness/be/skills/grill-api-unit/SKILL.md +2 -2
  24. package/harness/common/rules/artifactgraph.mdc +2 -2
  25. package/harness/common/rules/cross-repo-index.mdc +2 -2
  26. package/harness/common/rules/platform-code-size.mdc +5 -5
  27. package/harness/common/rules/team-flow-harness-state.mdc +4 -4
  28. package/harness/common/skills/business-impact-review/SKILL.md +1 -1
  29. package/harness/common/skills/configure-repo-maps/SKILL.md +1 -1
  30. package/harness/common/skills/docs-mark/SKILL.md +4 -4
  31. package/harness/docs/extracts/agent-design-context.md +136 -0
  32. package/harness/docs/extracts/extract-registry.docs.json +9 -3
  33. package/harness/docs/extracts/ir-read-only.md +42 -0
  34. package/harness/docs/rules/agent-compliance.mdc +5 -1
  35. package/harness/docs/rules/docs-hub.mdc +6 -6
  36. package/harness/docs/rules/flowgrid-process.mdc +5 -5
  37. package/harness/docs/rules/team-flow-grill.mdc +1 -1
  38. package/harness/docs/rules/team-flow-spec.mdc +5 -5
  39. package/harness/docs/skills/adopt/SKILL.md +1 -1
  40. package/harness/docs/skills/api/SKILL.md +2 -2
  41. package/harness/docs/skills/api-spec/SKILL.md +4 -0
  42. package/harness/docs/skills/build-templates/SKILL.md +1 -1
  43. package/harness/docs/skills/call-external/SKILL.md +1 -1
  44. package/harness/docs/skills/cross-entity-service/SKILL.md +1 -1
  45. package/harness/docs/skills/db-erd/SKILL.md +2 -2
  46. package/harness/docs/skills/grill/SKILL.md +1 -1
  47. package/harness/docs/skills/grill-api-spec/SKILL.md +3 -3
  48. package/harness/docs/skills/grill-bqa/SKILL.md +2 -2
  49. package/harness/docs/skills/grill-dev/SKILL.md +31 -13
  50. package/harness/docs/skills/grill-docs/SKILL.md +2 -2
  51. package/harness/docs/skills/grill-hub-prd/SKILL.md +1 -1
  52. package/harness/docs/skills/openapi/SKILL.md +3 -3
  53. package/harness/docs/skills/risk-register/SKILL.md +8 -8
  54. package/harness/docs/skills/spec/SKILL.md +20 -12
  55. package/harness/docs/skills/update-spec/SKILL.md +17 -7
  56. package/harness/docs/skills/user-flow/SKILL.md +4 -2
  57. package/harness/fe/adapters/dotnet-line/skills/framework-rules/SKILL.md +2 -2
  58. package/harness/fe/adapters/nextjs/skills/framework-rules/SKILL.md +2 -2
  59. package/harness/fe/adapters/nuxt4/skills/framework-rules/SKILL.md +2 -2
  60. package/harness/fe/rules/cross-repo-index-routing.mdc +1 -1
  61. package/harness/fe/rules/flowgrid-test-optional-accelerators.mdc +3 -3
  62. package/harness/fe/rules/team-flow-prototype.mdc +13 -13
  63. package/harness/fe/rules/team-flow-unit.mdc +6 -6
  64. package/harness/fe/skills/grill-prototype/SKILL.md +2 -2
  65. package/harness/fe/skills/grill-test/SKILL.md +1 -1
  66. package/harness/fe/skills/grill-unit/SKILL.md +2 -2
  67. package/harness/fe/skills/grill-wire/SKILL.md +1 -1
  68. package/harness/fe/skills/model/SKILL.md +4 -4
  69. package/harness/fe/skills/prototype/SKILL.md +23 -11
  70. package/harness/fe/skills/test/SKILL.md +3 -3
  71. package/harness/fe/skills/unit/SKILL.md +4 -4
  72. package/harness/fe/skills/wire/SKILL.md +5 -5
  73. package/harness/shared/rules/flowgrid-code-optional-integrations.mdc +7 -7
  74. package/harness/tests/rules/cross-repo-index-routing.mdc +1 -1
  75. package/harness/tests/rules/flowgrid-test-optional-accelerators.mdc +3 -3
  76. package/harness/tests/rules/plans-docs-first.mdc +5 -5
  77. package/harness/tests/skills/grill-testcase/SKILL.md +4 -4
  78. package/harness/tests/skills/scenario/SKILL.md +3 -3
  79. package/harness/tests/skills/testcase/SKILL.md +2 -2
  80. package/package.json +1 -1
  81. package/templates/shared/bundle-authoring.md +13 -6
  82. package/templates/shared/default-layout.ejs +47 -2
  83. package/templates/shared/feature.bundle.yaml +29 -1
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Two-step audit for bundle interactionCases (invoked only from audit-bundle-gaps on *.bundle.yaml).
3
+ * See harness/docs/extracts/agent-design-context.md — do not run against ir/spec or ir/design.
4
+ */
5
+
6
+ function countMutationActions(design) {
7
+ const actions = design?.actions
8
+ if (!Array.isArray(actions)) return 0
9
+ return actions.filter((a) => a && (a.executionContract || a.apiRef)).length
10
+ }
11
+
12
+ export function interactionCasesComplexityTriggers(bundle) {
13
+ const design = bundle?.design ?? {}
14
+ const statuses = design?.stateMatrix?.recordStatuses
15
+ const statusCount = Array.isArray(statuses) ? statuses.length : 0
16
+ const mutations = countMutationActions(design)
17
+ const scenarios = bundle?.userStories?.scenarios
18
+ const scenarioCount = Array.isArray(scenarios) ? scenarios.length : 0
19
+ const listOnly =
20
+ design?.codegen?.profile === 'list' ||
21
+ String(bundle?.gen?.codegen?.profile || '') === 'list'
22
+
23
+ return {
24
+ complex:
25
+ statusCount >= 3 ||
26
+ mutations >= 2 ||
27
+ (!listOnly && scenarioCount >= 4) ||
28
+ Boolean(design?.stateMatrix?.behaviors?.length >= 3),
29
+ statusCount,
30
+ mutations,
31
+ scenarioCount,
32
+ }
33
+ }
34
+
35
+ /**
36
+ * @param {Record<string, unknown>} bundle parsed bundle YAML
37
+ * @param {{ addGap: Function, addConfirm: Function, addWarning: Function }} hooks
38
+ */
39
+ export function auditInteractionCases(bundle, hooks) {
40
+ const { addGap, addConfirm, addWarning } = hooks
41
+ const ic = bundle?.interactionCases
42
+ const { complex, statusCount, mutations } = interactionCasesComplexityTriggers(bundle)
43
+
44
+ if (ic == null) {
45
+ if (!complex) return
46
+ addConfirm(
47
+ 'CONFIRM_INTERACTION_CASES_POLICY',
48
+ 'interactionCases',
49
+ 'Screen has complex state/actions — declare interactionCases (IC-* + sequenceDiagram)?',
50
+ [
51
+ '(Recommended) Yes — set interactionCases.policy: required and items[]',
52
+ 'No — simple screen (set interactionCases.policy: skip + skipReason)',
53
+ 'Other — note in qa/',
54
+ ],
55
+ 0,
56
+ )
57
+ return
58
+ }
59
+
60
+ const policy = ic.policy
61
+ if (policy === 'skip') {
62
+ if (!String(ic.skipReason || '').trim()) {
63
+ addWarning(
64
+ 'INTERACTION_CASES_SKIP_NO_REASON',
65
+ 'interactionCases.skipReason',
66
+ 'interactionCases.policy is skip but skipReason is empty.',
67
+ 'Declare skipReason explaining why L2 sequences are not needed.',
68
+ )
69
+ }
70
+ return
71
+ }
72
+
73
+ const items = Array.isArray(ic.items) ? ic.items : []
74
+
75
+ if (policy === 'required' && items.length === 0) {
76
+ addGap(
77
+ 'INTERACTION_CASES_ITEMS_MISSING',
78
+ 'critical',
79
+ 'interactionCases.items',
80
+ 'interactionCases.policy is required but items[] is empty.',
81
+ 'Add at least one IC-* item with description and sequenceDiagram.',
82
+ )
83
+ return
84
+ }
85
+
86
+ if (items.length === 0) return
87
+
88
+ const actionIds = new Set(
89
+ (bundle?.design?.actions || [])
90
+ .map((a) => a?.id)
91
+ .filter(Boolean),
92
+ )
93
+ const statuses = new Set(bundle?.design?.stateMatrix?.recordStatuses || [])
94
+
95
+ for (let i = 0; i < items.length; i++) {
96
+ const item = items[i]
97
+ const base = `interactionCases.items[${i}]`
98
+ if (!item?.id) {
99
+ addGap(
100
+ 'INTERACTION_CASES_MISSING_ID',
101
+ 'critical',
102
+ `${base}.id`,
103
+ 'Interaction case missing id (use IC-*).',
104
+ 'Declare id: IC-SUBMIT-HAPPY',
105
+ )
106
+ } else if (!/^IC-[A-Z0-9][A-Z0-9-]*$/i.test(String(item.id))) {
107
+ addWarning(
108
+ 'INTERACTION_CASES_ID_FORMAT',
109
+ `${base}.id`,
110
+ `Interaction case id "${item.id}" should match IC-* pattern.`,
111
+ 'Rename to IC-<DOMAIN>-<CASE> (e.g. IC-SUBMIT-409).',
112
+ )
113
+ }
114
+ if (!String(item?.title || '').trim()) {
115
+ addGap(
116
+ 'INTERACTION_CASES_MISSING_TITLE',
117
+ 'critical',
118
+ `${base}.title`,
119
+ 'Interaction case missing title.',
120
+ 'Add short title for reviewers and agents.',
121
+ )
122
+ }
123
+ if (!String(item?.description || '').trim()) {
124
+ addGap(
125
+ 'INTERACTION_CASES_MISSING_DESCRIPTION',
126
+ 'critical',
127
+ `${base}.description`,
128
+ 'Interaction case missing description (user case prose).',
129
+ 'Describe user steps and expected UI/API feedback.',
130
+ )
131
+ }
132
+ const seq = String(item?.sequenceDiagram || '')
133
+ if (!seq.includes('sequenceDiagram')) {
134
+ addGap(
135
+ 'INTERACTION_CASES_MISSING_SEQUENCE',
136
+ 'critical',
137
+ `${base}.sequenceDiagram`,
138
+ 'Interaction case missing Mermaid sequenceDiagram.',
139
+ 'Add sequenceDiagram with alt/else for error paths when applicable.',
140
+ )
141
+ } else if (!/alt\s+/i.test(seq) && complex) {
142
+ addWarning(
143
+ 'INTERACTION_CASES_NO_ALT',
144
+ `${base}.sequenceDiagram`,
145
+ 'Sequence diagram has no alt/else block — recommend at least one error branch.',
146
+ 'Model validation, 409, or timeout with alt/else.',
147
+ )
148
+ }
149
+ const actionId = item?.links?.actionId
150
+ if (actionId && actionIds.size && !actionIds.has(actionId)) {
151
+ addWarning(
152
+ 'INTERACTION_CASES_UNKNOWN_ACTION',
153
+ `${base}.links.actionId`,
154
+ `links.actionId "${actionId}" not found in design.actions.`,
155
+ 'Align with an existing action id or add the action.',
156
+ )
157
+ }
158
+ const st = item?.links?.recordStatus
159
+ if (st && statuses.size && !statuses.has(st)) {
160
+ addWarning(
161
+ 'INTERACTION_CASES_UNKNOWN_STATUS',
162
+ `${base}.links.recordStatus`,
163
+ `links.recordStatus "${st}" not in stateMatrix.recordStatuses.`,
164
+ `Use one of: ${[...statuses].join(', ')}`,
165
+ )
166
+ }
167
+ }
168
+
169
+ if (policy === 'required' && mutations >= 2 && items.length < mutations) {
170
+ addWarning(
171
+ 'INTERACTION_CASES_FEW_ITEMS',
172
+ 'interactionCases.items',
173
+ `Only ${items.length} interaction case(s) for ${mutations} mutation action(s).`,
174
+ 'Consider one IC-* per critical mutation path (happy + conflict).',
175
+ )
176
+ }
177
+
178
+ if (complex && !policy) {
179
+ addWarning(
180
+ 'INTERACTION_CASES_POLICY_UNSET',
181
+ 'interactionCases.policy',
182
+ 'interactionCases present but policy not set to required or skip.',
183
+ 'Set policy: required or policy: skip with skipReason.',
184
+ )
185
+ }
186
+ }
@@ -20,6 +20,7 @@ import {
20
20
  import { applyOpenQaField } from './open-qa.mjs'
21
21
  import { applyDesignApiFrom01 } from './hydrate-design-api.mjs'
22
22
  import { isPlaceholderLegacy, projectBusinessPage } from './project-business-layout.mjs'
23
+ import { applyInteractionCasesToIr } from './interaction-cases.mjs'
23
24
 
24
25
  export function bundlePageId(bundle) {
25
26
  const v = bundle?.['page-id'] ?? bundle?.pageId ?? bundle?.id
@@ -39,6 +40,12 @@ export function buildIrFromBundle(bundle) {
39
40
  const pageId = bundlePageId(bundle)
40
41
  const legacy = { id: pageId, ...(bundle.legacy ?? {}) }
41
42
  const design = buildDesignIr(bundle, designSpec, gen)
43
+ if (bundle.interactionCases != null) {
44
+ delete spec.interactionCases
45
+ applyInteractionCasesToIr(spec, design, bundle.interactionCases)
46
+ } else if (spec.interactionCases) {
47
+ delete spec.interactionCases
48
+ }
42
49
 
43
50
  return { spec, legacy, design, designSpec, gen }
44
51
  }
@@ -15,6 +15,7 @@ export const BUNDLE_META_KEYS = [
15
15
  'scopeIn',
16
16
  'nonGoals',
17
17
  'userFlows',
18
+ 'interactionCases',
18
19
  'nfr',
19
20
  'userStories',
20
21
  'specOrigin',
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Split bundle interactionCases → ir/spec (prose) + ir/design (sequenceDiagram only).
3
+ */
4
+
5
+ /**
6
+ * @param {unknown} interactionCases
7
+ * @returns {{ specPart: object|null, designPart: object|null }}
8
+ */
9
+ export function partitionInteractionCasesForIr(interactionCases) {
10
+ if (!interactionCases || typeof interactionCases !== 'object') {
11
+ return { specPart: null, designPart: null }
12
+ }
13
+ const { policy, skipReason, items } = interactionCases
14
+ const specPart = {
15
+ ...(policy != null ? { policy } : {}),
16
+ ...(skipReason != null && String(skipReason).trim() ? { skipReason } : {}),
17
+ items: Array.isArray(items)
18
+ ? items.map((item) => {
19
+ if (!item || typeof item !== 'object') return item
20
+ const { id, title, description, links } = item
21
+ return { id, title, description, links }
22
+ })
23
+ : [],
24
+ }
25
+ const designItems = Array.isArray(items)
26
+ ? items
27
+ .filter((item) => item && typeof item === 'object' && item.sequenceDiagram)
28
+ .map(({ id, sequenceDiagram }) => ({ id, sequenceDiagram }))
29
+ : []
30
+ const designPart = designItems.length ? { items: designItems } : null
31
+ return { specPart, designPart }
32
+ }
33
+
34
+ /**
35
+ * @param {Record<string, unknown>} spec
36
+ * @param {Record<string, unknown>} design
37
+ * @param {unknown} interactionCases from bundle
38
+ */
39
+ export function applyInteractionCasesToIr(spec, design, interactionCases) {
40
+ const { specPart, designPart } = partitionInteractionCasesForIr(interactionCases)
41
+ if (!specPart && !designPart) return
42
+ if (specPart && (specPart.policy || specPart.skipReason || specPart.items?.length)) {
43
+ spec.interactionCases = specPart
44
+ }
45
+ if (designPart) design.interactionCases = designPart
46
+ }
@@ -34,7 +34,7 @@ async function main() {
34
34
  const mdRel = mdOut ? path.relative(process.cwd(), mdOut) : null
35
35
  const genDir = mdOut ? path.dirname(mdOut) : null
36
36
  const extra = genDir
37
- ? ['data-model.md', 'api.md']
37
+ ? ['data-model.md', 'api.md', 'design.md']
38
38
  .filter((name) => fs.existsSync(path.join(genDir, name)))
39
39
  .map((name) => path.relative(process.cwd(), path.join(genDir, name)))
40
40
  : []
@@ -8,9 +8,9 @@ disable-model-invocation: true
8
8
 
9
9
  **Owner:** Platform DNA (`--type=be|monolith --be-adapter=dotnet-integration`)
10
10
 
11
- .NET integration host · bộ code grill/gen first when applicable.
11
+ .NET integration host · code repo grill/gen first when applicable.
12
12
 
13
- ## Gen trước (code)
13
+ ## Gen first (code)
14
14
 
15
15
  1. Prefer codegen / existing templates before free-form scaffolding
16
16
  2. AI fills gaps only — do not duplicate generated surfaces
@@ -8,11 +8,11 @@ disable-model-invocation: true
8
8
 
9
9
  **Owner:** Platform DNA (`--type=be|monolith --be-adapter=fastapi`)
10
10
 
11
- FastAPI · modular packages · bộ code grill/gen first.
11
+ FastAPI · modular packages · code repo grill/gen first.
12
12
 
13
- ## Gen trước (code)
13
+ ## Gen first (code)
14
14
 
15
- 1. bộ code `gen` / repo shim from IR already grilled
15
+ 1. code repo `gen` / repo shim from IR already grilled
16
16
  2. AI only fills `#needs-*` / gaps not yet in `registries/`
17
17
  3. Do not hand-write boilerplate codegen already covers
18
18
 
@@ -8,11 +8,11 @@ disable-model-invocation: true
8
8
 
9
9
  **Owner:** Platform DNA (`--type=be|monolith --be-adapter=laravel`)
10
10
 
11
- Laravel · `nwidart/laravel-modules` (modules-v1) · bộ code grill/gen first.
11
+ Laravel · `nwidart/laravel-modules` (modules-v1) · code repo grill/gen first.
12
12
 
13
- ## Gen trước (code)
13
+ ## Gen first (code)
14
14
 
15
- 1. bộ code `gen` / repo shim from IR already grilled
15
+ 1. code repo `gen` / repo shim from IR already grilled
16
16
  2. AI only fills `#needs-*` / gaps not yet in registries
17
17
  3. Do not hand-write module scaffolding codegen already covers
18
18
 
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: api
3
- description: /api — backend API generation through bộ code BE adapters.
3
+ description: /api — backend API generation through BE code repo adapters.
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
7
7
  # /api — Backend API
8
8
 
9
- **Owner:** bộ code (`--type=be`)
9
+ **Owner:** code repo (`--type=be`)
10
10
  **Adapters:** `fastapi` · `laravel` · `dotnet-integration` · `nestjs`
11
11
 
12
12
  ## Generate
@@ -52,7 +52,7 @@ FE models (not this skill): `flowgrid contract-gen:dry -- --spec /path/to/ir/des
52
52
 
53
53
  ## Route
54
54
 
55
- Architecture/C4 → bộ docs (`FLOWGRID_DOCS_ROOT`); IR via explicit `--spec` /
55
+ Architecture/C4 → docs hub (`FLOWGRID_DOCS_ROOT`); IR via explicit `--spec` /
56
56
  `FLOWGRID_DOCS_ROOT` when configured — never ArtifactGraph as the docs
57
57
  bridge. This-repo conventions → local CodeGraph if present; other repo X →
58
58
  only Platform DNA-wired `codegraph-<key>`. ArtifactGraph = local allowlist
@@ -87,7 +87,7 @@ warns and uses entity-local CRUD defaults.
87
87
 
88
88
  ```text
89
89
  if ArtifactGraph available: allowlist/recommend API generation
90
- else: execute bộ code adapter directly
90
+ else: execute code repo adapter directly
91
91
 
92
92
  if CodeGraph available for this checkout (`codegraph-<key>`): inspect existing module conventions/callers
93
93
  else: targeted repository search — never a workspace-parent graph
@@ -1,12 +1,12 @@
1
1
  ---
2
2
  name: api-unit
3
- description: /unit — backend API unit test generation via bộ code BE adapters.
3
+ description: /unit — backend API unit test generation via BE code repo adapters.
4
4
  disable-model-invocation: true
5
5
  ---
6
6
 
7
7
  # /unit — Backend API Unit Tests
8
8
 
9
- **Owner:** bộ code (`--type=be`)
9
+ **Owner:** code repo (`--type=be`)
10
10
  **Adapters:** `fastapi` · `laravel` · `nestjs`
11
11
 
12
12
  > `dotnet-integration` emits test source during its primary API pass; it has no
@@ -48,7 +48,7 @@ Requires a prior `01-backend-spec.yaml` under the docs hub API folder.
48
48
 
49
49
  ## Route
50
50
 
51
- Architecture/C4 → bộ docs (`FLOWGRID_DOCS_ROOT`); spec via explicit `--spec` /
51
+ Architecture/C4 → docs hub (`FLOWGRID_DOCS_ROOT`); spec via explicit `--spec` /
52
52
  `FLOWGRID_DOCS_ROOT` when configured — never ArtifactGraph as the docs
53
53
  bridge. This-repo conventions → local CodeGraph if present; other repo X →
54
54
  only Platform DNA-wired `codegraph-<key>`. ArtifactGraph = local allowlist
@@ -64,7 +64,7 @@ hints only.
64
64
 
65
65
  ```text
66
66
  if ArtifactGraph available: allowlist/recommend API unit generation
67
- else: execute bộ code adapter directly
67
+ else: execute code repo adapter directly
68
68
 
69
69
  if CodeGraph available for this checkout (`codegraph-<key>`): inspect existing test conventions
70
70
  else: targeted repository search — never a workspace-parent graph
@@ -8,7 +8,7 @@ disable-model-invocation: true
8
8
 
9
9
  Run after `npm run codegen:api:dry` / `flowgrid api-gen:dry` and after implementation.
10
10
 
11
- **Owner:** bộ code (`--type=be`). Docs hub is **read-only**.
11
+ **Owner:** code repo (`--type=be`). Docs hub is **read-only**.
12
12
 
13
13
  ## Target / ID Resolution Rule
14
14
 
@@ -36,7 +36,7 @@ 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`.
39
+ **CLI (quantitative):** `flowgrid audit api` on `01`; when portal bundle exists → `flowgrid audit fe-be` on sibling `*.bundle.yaml`.
40
40
 
41
41
  ## Accelerators (optional)
42
42
 
@@ -47,7 +47,7 @@ else: scoped contract-to-code comparison
47
47
  if codegraph-<repo-key> for this checkout: callers/routes/jobs/listeners
48
48
  else: targeted repository search
49
49
 
50
- architecture IDs / C4 → bộ docs (FLOWGRID_DOCS_ROOT), never CodeGraph
50
+ architecture IDs / C4 → docs hub (FLOWGRID_DOCS_ROOT), never CodeGraph
51
51
  ```
52
52
 
53
53
  Missing accelerators never block the audit. Complete each scoped model or
@@ -6,7 +6,7 @@ disable-model-invocation: true
6
6
 
7
7
  # /grill-unit
8
8
 
9
- **Owner:** bộ code · audit gate before BE unit test generation.
9
+ **Owner:** code repo · audit gate before BE unit test generation.
10
10
 
11
11
  Run after `npm run codegen:api:unit:dry` / `flowgrid api-unit-gen:dry` and
12
12
  before committing generated test code.
@@ -50,7 +50,7 @@ else: scoped spec-to-test comparison
50
50
  if codegraph-<repo-key> for this checkout: callers/routes/existing test patterns
51
51
  else: targeted repository search
52
52
 
53
- architecture IDs / C4 → bộ docs (FLOWGRID_DOCS_ROOT), never CodeGraph
53
+ architecture IDs / C4 → docs hub (FLOWGRID_DOCS_ROOT), never CodeGraph
54
54
  ```
55
55
 
56
56
  Missing accelerators never block the grill. Complete each scoped model or
@@ -14,9 +14,9 @@ alwaysApply: false
14
14
 
15
15
  ## Cross-repo routing
16
16
 
17
- - Architecture ID / C4 → bộ docs (`FLOWGRID_DOCS_ROOT`), not CodeGraph and not
17
+ - Architecture ID / C4 → docs hub (`FLOWGRID_DOCS_ROOT`), not CodeGraph and not
18
18
  ArtifactGraph.
19
- - IR / registry / generation → bộ code / bộ test pointers
19
+ - IR / registry / generation → code repo / tests hub pointers
20
20
  (`FLOWGRID_DOCS_ROOT`, `FLOWGRID_DOCS_ROOT`, `FLOWGRID_TESTS_DOC`).
21
21
  - Symbol / call-graph of repo X → `codegraph-<key>` MCP for checkout X.
22
22
  - ArtifactGraph is local-only: never follow those pointers, never read repo
@@ -9,13 +9,13 @@ Do not merge every repository into a single workspace graph (the parent folder
9
9
  must never be indexed). "Cross-repo" means a skill/rule knows how to reach the
10
10
  **correct per-repo index**, one repository at a time.
11
11
 
12
- **Owner:** Platform DNA. FlowGrid harness rules (bộ docs, bộ process, …) install this same
12
+ **Owner:** Platform DNA. FlowGrid harness rules (docs hub, process hub, …) install this same
13
13
  filename only when DNA is absent, so a destination never carries duplicate
14
14
  `alwaysApply` routing rules under different names.
15
15
 
16
16
  Route by intent:
17
17
 
18
- - Need an architecture ID or C4 path -> bộ docs MCP (`FLOWGRID_DOCS_ROOT`). Never
18
+ - Need an architecture ID or C4 path -> docs hub MCP (`FLOWGRID_DOCS_ROOT`). Never
19
19
  CodeGraph for architecture Markdown.
20
20
  - Need IR / registry / generation -> the pointer kit
21
21
  (`FLOWGRID_DOCS_ROOT`, `FLOWGRID_DOCS_ROOT`, `FLOWGRID_TESTS_DOC`).
@@ -8,17 +8,17 @@ alwaysApply: false
8
8
 
9
9
  Soft limits — split in the same PR when exceeded.
10
10
 
11
- | Vượt ~200 dòng/file | Tách | Gợi ý Tag DSL (`/docs-mark`) |
11
+ | Exceeds ~200 lines/file | Split | Suggest Tag DSL (`/docs-mark`) |
12
12
  |---------------------|------|------------------------------|
13
- | Page `.vue` | Composable + sub-component | `#needs-component: sub-{name}:MoXxx` hoặc `#common-ui` |
13
+ | Page `.vue` | Composable + sub-component | `#needs-component: sub-{name}:MoXxx` or `#common-ui` |
14
14
  | Composable | `useXxxForm`, `useXxxList`, … | `#common-ui` / `#needs-ui` |
15
- | Service / store | File theo aggregate; action phức tạp → service | `#cross-service` / `#cross-entity-service` / `#needs-service` |
15
+ | Service / store | File per aggregate; complex action → service | `#cross-service` / `#cross-entity-service` / `#needs-service` |
16
16
  | E2E spec | Page Object + helper | `#e2e-test` bundle split |
17
17
 
18
- | Vượt ~20 dòng/function | Tách | Gợi ý Tag DSL (`/docs-mark`) |
18
+ | Exceeds ~20 lines/function | Split | Suggest Tag DSL (`/docs-mark`) |
19
19
  |------------------------|------|------------------------------|
20
20
  | Submit handler | `buildPayload`, `validateBeforeSubmit`, `handleApiError` | `#needs-service` / local helper |
21
21
  | Map/transform | Pure helpers / computed | `#derived-data` |
22
22
 
23
23
  No padding files with blank lines. Component split: `platform-component-split.mdc`.
24
- Khi file/function chạm ngưỡng vượt giới hạn, AI Agent cần chủ động đề xuất gán tag tương ứng (thông qua `/docs-mark`) và cập nhật registry (`registries/design.registry.json` hoặc `registries/common.registry.json`) để tái sử dụng sau này.
24
+ When a file or function hits an exceed threshold, the agent should proactively propose the matching tag (via `/docs-mark`) and update the registry (`registries/design.registry.json` or `registries/common.registry.json`) for reuse later.
@@ -6,7 +6,7 @@ alwaysApply: false
6
6
 
7
7
  # Harness State
8
8
 
9
- - `feature_list.json` — scope, không tự đánh done khi chưa verify
10
- - `progress.md` — handoff session tiếp theo
11
- - `registries/page-lifecycle.registry.json` + `base-docs/platform/toolchain/PAGE-LIFECYCLE.md` — stage cao nhất từng route; `portal:gen` / `portal:remove` / `portal:lifecycle sync` tự cập nhật
12
- - Khi command public cập nhật phase, ghi rõ: command, file đã đổi, verify đã chạy/chưa chạy, blocker còn lại.
9
+ - `feature_list.json` — scope; do not mark done without verification
10
+ - `progress.md` — handoff for the next session
11
+ - `registries/page-lifecycle.registry.json` + `base-docs/platform/toolchain/PAGE-LIFECYCLE.md` — highest stage per route; `portal:gen` / `portal:remove` / `portal:lifecycle sync` update automatically
12
+ - When a public command updates phase, record clearly: command, files changed, verify run or not, remaining blockers.
@@ -90,7 +90,7 @@ if CodeGraph available: changed symbols + callers + call graph — for repo X us
90
90
  open repo's index; unindexed repo → report `cd <root> && codegraph init`
91
91
  else: targeted repository search/read
92
92
 
93
- if bộ docs available: map process steps to CMP/CTR/FLOW docs via FLOWGRID_DOCS_ROOT
93
+ if docs hub available: map process steps to CMP/CTR/FLOW docs via FLOWGRID_DOCS_ROOT
94
94
  (never CodeGraph for architecture Markdown)
95
95
  else: repository conventions/search
96
96
 
@@ -55,6 +55,6 @@ legacy ERP at D:\legacy\erp, key legacy-erp
55
55
  ## After Write
56
56
 
57
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`).
58
+ 2. If paths conflict with init/harness MCP: `flowgrid repo-maps align` (member confirms each hub `docs` / `tests`).
59
59
  3. One-way refresh from config: `flowgrid repo-maps sync --from-config` then `flowgrid harness sync`.
60
60
  4. Optional CodeGraph: `platform-dna codegraph:wire` · `codegraph init` per checkout.
@@ -31,13 +31,13 @@ fallbacks.
31
31
  | UI | `registries/design.registry.json` | `#needs-component:` `#needs-ui:` `#shell:` |
32
32
  | Logic | `registries/common.registry.json` | `#common:*` `#needs-common:*` |
33
33
 
34
- Executable registry validation is **bộ code FE** (or product scripts on the
34
+ Executable registry validation is **FE code repo** (or product scripts on the
35
35
  FE checkout). On docs hub:
36
36
 
37
37
  ```text
38
38
  if ArtifactGraph available:
39
39
  artifactgraph_allowlist_check(registryValidate|commonRegistry)
40
- artifactgraph_recommend_command → hand off to bộ code FE
40
+ artifactgraph_recommend_command → hand off to FE code repo
41
41
  else:
42
42
  note pending FE registry validate; do not invent local shell fallbacks
43
43
  ```
@@ -58,8 +58,8 @@ else:
58
58
 
59
59
  ## Handoff
60
60
 
61
- bộ code FE / product: `flowgrid gen:dry` (or repo shim) after marks change,
62
- when that lane is available. Missing bộ code is a pending handoff, not a
61
+ FE code repo / product: `flowgrid gen:dry` (or repo shim) after marks change,
62
+ when that lane is available. Missing code repo is a pending handoff, not a
63
63
  docs failure.
64
64
 
65
65
  ## Compatibility