cabloy 5.1.151 → 5.1.153

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 (42) hide show
  1. package/.cabloy-version +1 -1
  2. package/.claude/skills/cabloy-module-removal/SKILL.md +1 -1
  3. package/.claude/skills/cabloy-resource-field-update/SKILL.md +1 -1
  4. package/.claude/skills/cabloy-spec-generation/SKILL.md +1 -1
  5. package/.claude/skills/cabloy-spec-generation/references/repo-aware-discovery.md +1 -1
  6. package/.claude/skills/cabloy-workflow/SKILL.md +13 -14
  7. package/.claude/skills/cabloy-workflow/evals/evals.json +4 -4
  8. package/CHANGELOG.md +20 -0
  9. package/CLAUDE.md +3 -3
  10. package/package.json +1 -1
  11. package/repo-docs/.vitepress/config.mjs +5 -0
  12. package/repo-docs/ai/cli-to-skill-map.md +19 -0
  13. package/repo-docs/ai/docs-skills-rules-mapping.md +21 -6
  14. package/repo-docs/ai/future-skill-roadmap.md +17 -72
  15. package/repo-docs/ai/introduction.md +15 -5
  16. package/repo-docs/ai/playbook-spec-execution.md +144 -0
  17. package/repo-docs/ai/playbook-spec-generation.md +155 -0
  18. package/repo-docs/ai/repo-guidance.md +9 -5
  19. package/repo-docs/ai/rules-and-config.md +2 -2
  20. package/repo-docs/ai/skills.md +4 -0
  21. package/repo-docs/ai/virtual-decorator-guidance.md +1 -1
  22. package/repo-docs/backend/introduction.md +1 -1
  23. package/repo-docs/frontend/model-resource-cookbook.md +38 -7
  24. package/repo-docs/frontend/model-resource-usage-guide.md +2 -1
  25. package/repo-docs/frontend/router-tabs-introduction.md +1 -1
  26. package/repo-docs/frontend/use-state-data-best-practices.md +39 -6
  27. package/repo-docs/reference/package-map.md +4 -1
  28. package/repo-docs/reference/repo-scripts.md +25 -0
  29. package/repo-e2e/specs/cabloy-basic.spec.ts +69 -20
  30. package/test-results/.last-run.json +4 -2
  31. package/test-results/cabloy-basic-ATP-BASIC-SUM-58d8a-ry-states-and-Markdown-HTML/error-context.md +195 -0
  32. package/vona/pnpm-lock.yaml +81 -145
  33. package/zova/src/suite/a-commerce/modules/commerce-trade/src/page/payment/controller.tsx +3 -2
  34. package/zova/src/suite/a-training/modules/training-student/src/bean/tableCell.actionSummary.tsx +29 -6
  35. package/zova/src/suite/a-training/modules/training-student/src/config/locale/en-us.ts +1 -0
  36. package/zova/src/suite/a-training/modules/training-student/src/config/locale/zh-cn.ts +1 -0
  37. package/zova/src/suite/a-training/modules/training-student/src/model/student.ts +1 -1
  38. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/package.json +1 -1
  39. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/lib/mutationSuccess.ts +11 -0
  40. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/src/model/resource.ts +12 -7
  41. package/zova/src/suite-vendor/a-cabloy/modules/rest-resource/test/lib/mutationSuccess.test.ts +95 -0
  42. package/zova/src/suite-vendor/a-cabloy/package.json +2 -2
@@ -0,0 +1,144 @@
1
+ # Playbook: Execute an Approved Cabloy Specification Increment
2
+
3
+ Use this playbook to deliver one approved Cabloy specification increment from a bounded WBS item through implementation, scoped verification, retained evidence, and an accurate progress handoff.
4
+
5
+ The `cabloy-spec-execution` skill is a control plane. It coordinates an approved increment and its specialist workflow; it is not a second product authority, architecture authority, or code generator.
6
+
7
+ ## When to use this playbook
8
+
9
+ Use `cabloy-spec-execution` when you need to:
10
+
11
+ - implement one named `WBS-*` item
12
+ - execute an explicitly named, finite, approved phase with a defined closure boundary
13
+ - verify or close a named ATP or release-gate task
14
+ - turn one existing suite-plan increment into implementation and observed proof
15
+
16
+ Requests such as “implement the suite,” “finish all specs,” or “do the next phase” are not bounded enough. Select one WBS task, or explicitly approve a finite task list and its closure boundary, before implementation begins.
17
+
18
+ Use [Playbook: Plan a Cabloy Suite Specification](/ai/playbook-spec-generation) instead when the task changes a requirement, contract, dependency, scope boundary, or durable decision.
19
+
20
+ ## Establish the execution boundary first
21
+
22
+ Start by inspecting the active repository, edition marker, current revision, and working-tree state. Then build an execution dossier for the selected increment.
23
+
24
+ The dossier identifies:
25
+
26
+ - suite, edition, target WBS ID or approved finite task list, and closure boundary
27
+ - linked PRD, SRS, ADR, ATP, progress, and evidence records
28
+ - predecessor tasks and their required proof
29
+ - source ownership, affected areas, and explicit exclusions
30
+ - applicable tenant, authorization, privacy, lifecycle, transaction, concurrency, idempotency, audit, migration, SSR, and contract-loop constraints
31
+ - the specialist workflow that owns implementation
32
+ - approved verification procedures, expected redacted evidence, and allowed record updates
33
+ - blockers, unresolved `TODO(confirm)` items, excluded unsafe operations, and one next action
34
+
35
+ Require explicit approval of the dossier before source changes, meaningful verification, evidence/status updates, or specialist execution. Do not reserve a task by marking it `in-progress` before approved work actually starts.
36
+
37
+ ## Read authority before implementation
38
+
39
+ Read the suite records in this order:
40
+
41
+ 1. `README.md` for identity, topology, reading order, and authority map
42
+ 2. `prd.md`, `srs.md`, and applicable ADRs for product and technical authority
43
+ 3. the complete WBS task and its dependencies in `pdp-wbs.md`
44
+ 4. linked ATP procedures and release gates in `test-plan.md`
45
+ 5. `progress.md` for derived status, blockers, waivers, evidence pointers, and next proof
46
+ 6. linked evidence, runbooks, presentation records, or rollout records when they apply
47
+ 7. `implementation-gantt.svg` and `implementation-burndown.svg` as derived views to check for freshness, not authority
48
+
49
+ When records conflict, return to [Playbook: Plan a Cabloy Suite Specification](/ai/playbook-spec-generation) before implementation. Do not resolve an authority contradiction through an execution note, a chart edit, or a source workaround.
50
+
51
+ ## Stop at readiness gates
52
+
53
+ Do not begin the increment when any of these conditions applies:
54
+
55
+ - the WBS target, suite identity, ownership boundary, or required source fact is unresolved
56
+ - PRD, SRS, ADR, WBS, or ATP records conflict
57
+ - a controlling `TODO(confirm)` or unaccepted ADR remains
58
+ - a predecessor lacks its required completion state or evidence
59
+ - the selected task is already `verified`, `blocked`, or `deferred`
60
+ - overlapping working-tree changes cannot be classified for attribution
61
+ - material tenant, authorization, privacy, lifecycle, transaction, concurrency, idempotency, audit, migration, SSR, or ownership behavior is unspecified
62
+ - the proposed work expands scope or introduces a competing persistence, identity, or API authority
63
+
64
+ When adding a persisted field to an existing backend resource, stop and ask the user whether `vonaModule.fileVersion` should increment before changing `meta.version.ts` or the module schema path. A specification can provide context, but it does not replace this direct confirmation. Do not invent a migration strategy during execution.
65
+
66
+ ## Route the smallest approved increment
67
+
68
+ After approval, hand the smallest coherent unit to the specialist that owns its implementation.
69
+
70
+ | Work shape | Route |
71
+ | -------------------------------------------------------------------- | ---------------------------------------------------- |
72
+ | Vona module, entity, DTO, service, migration, or backend test | `cabloy-backend-scaffold` |
73
+ | Zova page, route, component, model, metadata, SSR, or frontend test | `cabloy-frontend-scaffold` |
74
+ | OpenAPI, generated consumers, reverse metadata, or consumer drift | `cabloy-contract-loop` |
75
+ | Master-detail, resource-field update, or module removal | The corresponding specialist skill |
76
+ | Requirement, scope, contract, dependency, or durable-decision change | `cabloy-spec-generation` or `cabloy-domain-planning` |
77
+
78
+ The execution workflow supplies the approved dossier and preserves the boundary; it does not replace a specialist's CLI-first procedure. Never hand-edit generated consumers, infer an unconfirmed site or flavor, or expand automatically into an adjacent WBS item.
79
+
80
+ ## Verify narrowly and retain evidence
81
+
82
+ Use the narrowest approved check first, then follow the linked ATP procedures and applicable release gates.
83
+
84
+ 1. run the scoped verification specified by the increment
85
+ 2. retain observed evidence using the suite's existing convention
86
+ 3. redact secrets, credentials, raw tokens, customer data, and provider identifiers
87
+ 4. record failures, waivers, invalidation, and supersession rather than erasing history
88
+ 5. update evidence before updating derived progress
89
+
90
+ Use status precisely:
91
+
92
+ - `in-progress` — approved implementation or verification has actually begun
93
+ - `implementation-complete` — source work is complete, but required ATP or release proof remains
94
+ - `verified` — all applicable WBS checks and ATPs have durable, linked, redacted observed evidence
95
+
96
+ A successful build, generation command, hook, manual walkthrough, screenshot, or unrelated test run is not by itself `verified` unless the authoritative test plan defines it as sufficient retained proof. Evidence is revision- and authority-scoped; mark old proof superseded or requiring rerun when relevant source or authority changes.
97
+
98
+ ## Refresh derived charts last
99
+
100
+ After evidence and progress are accurate, refresh the two derived views when the suite's authoritative Markdown follows the [chart input contract](/reference/repo-scripts#chart-input-contract). Refresh again when the suite README title or language changes:
101
+
102
+ ```bash
103
+ npm run spec:charts -- <suite>
104
+ # Use this non-mutating check when verifying an existing chart state:
105
+ npm run spec:charts:check -- <suite>
106
+ ```
107
+
108
+ The correct update order is:
109
+
110
+ ```text
111
+ evidence → progress → derived charts
112
+ ```
113
+
114
+ Use the check as a separate non-mutating freshness verification, such as CI or a review of an existing chart state. A passing chart check confirms only the supported chart input contract and generated-view freshness. It is not ATP proof, implementation proof, release approval, or a replacement for reviewing traceability and status semantics. Do not hand-edit an SVG to mask an authority conflict; correct the authoritative Markdown records and regenerate instead. Chart language follows the suite README.
115
+
116
+ Confirm the available root scripts and their input expectations in the active repository, especially when the work concerns a Cabloy Start checkout or a legacy suite.
117
+
118
+ ## Keep unsafe operations outside the increment
119
+
120
+ Without a separate explicit workflow and approval, do not:
121
+
122
+ - infer Cabloy Start runtime facts from Cabloy Basic
123
+ - run `npm run init`, reset or recreate a database, or reinstall dependencies as a first response to drift
124
+ - clean, reset, stash, check out, or discard the working tree
125
+ - deploy, publish, cut over, operate a provider or webhook, change credentials, or retain secrets
126
+ - commit or push
127
+ - fabricate evidence or promote status based only on planning artifacts, hooks, builds, or generated outputs
128
+ - continue to adjacent WBS work automatically
129
+
130
+ ## Leave a resumable handoff
131
+
132
+ Finish the increment with a concise record of:
133
+
134
+ 1. target WBS/phase, edition, revision, and working-tree classification
135
+ 2. implemented scope and explicit exclusions
136
+ 3. commands and procedures actually run
137
+ 4. observed evidence and its redacted location
138
+ 5. resulting status and its precise reason
139
+ 6. remaining blocker or evidence gap
140
+ 7. exactly one next action
141
+
142
+ A next action is a handoff, not authorization to execute another task. If it requires an authority change, return to [Playbook: Plan a Cabloy Suite Specification](/ai/playbook-spec-generation).
143
+
144
+ For the public boundaries between docs, skills, suite authority, and CLI workflows, read [Docs, Skills, Rules, and CLI Mapping](/ai/docs-skills-rules-mapping) and [CLI to Skill Map](/ai/cli-to-skill-map).
@@ -0,0 +1,155 @@
1
+ # Playbook: Plan a Cabloy Suite Specification
2
+
3
+ Use this playbook to create or maintain the repository-native planning record for a long-lived Cabloy business suite. It explains the public workflow behind the `cabloy-spec-generation` skill without replacing the skill's detailed decision tree.
4
+
5
+ A specification establishes product intent, technical contracts, delivery structure, acceptance procedures, and decision history. It does **not** prove that implementation, generated artifacts, tests, or acceptance evidence already exist.
6
+
7
+ ## When to use this playbook
8
+
9
+ Use `cabloy-spec-generation` when you need to:
10
+
11
+ - establish a new suite's PRD, SRS, WBS, test plan, progress register, and initial ADR
12
+ - extend an existing suite's authoritative planning records
13
+ - turn product intent into traceable delivery and acceptance records
14
+ - prepare an approved handoff for implementation
15
+
16
+ Use a different workflow when:
17
+
18
+ - provider, suite, or module identity is unresolved — use `cabloy-domain-planning`
19
+ - the task is approved backend or frontend scaffolding — use `cabloy-backend-scaffold` or `cabloy-frontend-scaffold`
20
+ - the task is Vona/Zova contract synchronization or generated-consumer drift — use `cabloy-contract-loop`
21
+ - the task is one already approved, bounded WBS increment — use [Playbook: Execute an Approved Cabloy Specification Increment](/ai/playbook-spec-execution)
22
+
23
+ ## Start with repository and edition discovery
24
+
25
+ Before naming a suite, describing source topology, or recommending a site, flavor, UI, SSR, or command path:
26
+
27
+ 1. inspect the active repository root and edition marker
28
+ 2. inspect the root `package.json`, `CLAUDE.md`, relevant CLI entrypoints, and existing suite records
29
+ 3. separate observed source facts from confirmed user inputs, proposed targets, and `TODO(confirm from active source)` items
30
+
31
+ Cabloy Basic and Cabloy Start share the planning model, but their runtime details can differ. Do not carry a Basic command, site identifier, flavor, UI assumption, or generated-output path into Start without confirming it in the active Start source.
32
+
33
+ Read [Edition Detection for AI Workflows](/ai/edition-detection), [Repo Guidance](/ai/repo-guidance), [Repo Scripts](/reference/repo-scripts), and [Package Map](/reference/package-map) before making repository-specific claims.
34
+
35
+ ## Classify the planning request
36
+
37
+ ### New suite baseline
38
+
39
+ A long-lived business domain normally receives the complete planning baseline under `repo-specs/<suite>/`. The specification should be suite-first, name capability modules by business responsibility, and avoid inventing a competing persistence, identity, or authorization owner.
40
+
41
+ ### Existing suite extension
42
+
43
+ Read the existing README and authority map first. Update the owning PRD, SRS, or ADR before downstream WBS, test-plan, progress, or evidence references. Preserve existing identifiers, accepted decisions, history, and evidence conventions rather than replacing them with a fresh parallel record.
44
+
45
+ ### Proportionate planning
46
+
47
+ A disposable demo, tutorial, or isolated utility can use a smaller record only when the requester explicitly selects that scope. Do not reduce the planning baseline for a domain expected to grow merely because its first increment is small.
48
+
49
+ ### Unresolved identity
50
+
51
+ Stop before creating a planning directory when the provider, suite, or capability boundary is unclear. Route the identity decision to `cabloy-domain-planning` rather than creating a competing suite hierarchy.
52
+
53
+ ## Keep the authority chain explicit
54
+
55
+ Repository-native traceability flows in one direction:
56
+
57
+ ```text
58
+ PRD requirement → SRS contract → PDP/WBS task → ATP scenario → observed evidence
59
+ ```
60
+
61
+ Each record has a distinct role:
62
+
63
+ | Record | Authority |
64
+ | ---------------------- | --------------------------------------------------------------------------------------------------------- |
65
+ | `README.md` | Index, reading order, topology summary, and authority map |
66
+ | `prd.md` | Product outcomes, personas, scope, journeys, business rules, and launch criteria |
67
+ | `srs.md` | Technical contracts, ownership, data, tenant, authorization, lifecycle, API, and nonfunctional boundaries |
68
+ | `pdp-wbs.md` | Dependency order, bounded delivery tasks, completion checks, and contract-loop checkpoints |
69
+ | `test-plan.md` | Formal ATP scenarios, procedures, fixtures, expected proof, and release gates |
70
+ | `decisions/*.md` | Durable suite decisions and their alternatives, consequences, and gates |
71
+ | Evidence records | Observed, redacted proof only |
72
+ | `progress.md` | Derived execution status, blockers, evidence links, and next proof |
73
+ | `implementation-*.svg` | Deterministic derived views of planning and progress records |
74
+
75
+ Update the upstream owner before downstream records. For example, a product or technical change belongs in the PRD, SRS, or ADR first; it is then traced into WBS tasks, ATP procedures, progress implications, and derived charts.
76
+
77
+ A proposed ADR is not an accepted decision. Progress cannot introduce a new requirement, contract, or durable boundary, and a chart cannot repair an authority conflict.
78
+
79
+ ## Build the planning baseline after confirmation
80
+
81
+ For a new long-lived suite, the normal core set is:
82
+
83
+ ```text
84
+ repo-specs/<suite>/
85
+ ├── README.md
86
+ ├── prd.md
87
+ ├── srs.md
88
+ ├── pdp-wbs.md
89
+ ├── test-plan.md
90
+ ├── progress.md
91
+ ├── implementation-gantt.svg
92
+ ├── implementation-burndown.svg
93
+ └── decisions/
94
+ └── 0001-*.md
95
+ ```
96
+
97
+ Add presentation contracts, staged rollout records, runbooks, additional ADRs, or an `evidence/` directory only when their scope is justified. Do not create empty evidence records to imply that testing or delivery has begun.
98
+
99
+ Before creating or replacing records, explicitly confirm at least:
100
+
101
+ - repository, edition, suite identity, and target directory
102
+ - intended product outcome, audiences, in-scope capabilities, and deferred scope
103
+ - confirmed and unresolved tenant, authorization, privacy, ownership, lifecycle, migration, and integration constraints
104
+ - site strategy at the level actually supported by current source and confirmed inputs
105
+ - required core documents and justified optional records
106
+ - unresolved decision gates and which WBS branches they block
107
+ - the initial delivery-status policy
108
+
109
+ Silence is not approval. Confirmation to generate records does not accept a durable ADR; retain an unaccepted decision as proposed. Initial delivery rows are normally `not-started`, `deferred`, or explicitly `blocked` unless actual prior evidence was intentionally carried forward.
110
+
111
+ ## Preserve traceability and status integrity
112
+
113
+ Use stable identifiers such as `PRD-*`, `SRS-*`, `WBS-*`, and `ATP-*`. Every referenced exact identifier must resolve to a formal definition in its owning document; a range, wildcard, or prose summary is not a substitute.
114
+
115
+ The status vocabulary is:
116
+
117
+ - `not-started`
118
+ - `in-progress`
119
+ - `implementation-complete`
120
+ - `verified`
121
+ - `blocked`
122
+ - `waived`
123
+ - `deferred`
124
+
125
+ `verified` requires retained, redacted, traceable observed proof. A planning record, a planned command, a generated scaffold, a screenshot, or an unrelated broad check does not automatically provide that proof.
126
+
127
+ ## Generate and check derived charts
128
+
129
+ For a new or substantially revised long-lived specification set whose authoritative Markdown follows the [chart input contract](/reference/repo-scripts#chart-input-contract), refresh the two derived views after changing the README title or language, WBS, test plan, or progress register:
130
+
131
+ ```bash
132
+ npm run spec:charts -- <suite>
133
+ # Use this non-mutating check when verifying an existing chart state:
134
+ npm run spec:charts:check -- <suite>
135
+ ```
136
+
137
+ The generator consumes the suite README, WBS, test plan, and progress register. It emits `implementation-gantt.svg` and `implementation-burndown.svg`; visible chart language follows the suite README. After refreshing charts, use the check when a separate freshness verification is needed, such as CI or a non-mutating review.
138
+
139
+ The check validates the supported chart input contract and generated-view freshness. It does **not** implement a WBS task, run an ATP, establish evidence, prove acceptance, or replace a review of traceability and status semantics. The charts are scope/order views, not schedule forecasts or a new status authority.
140
+
141
+ This current baseline does not require unchanged legacy suite records to be migrated solely to add charts. A legacy record that does not follow the chart input contract must not be treated as chart-compatible until a deliberate record-format normalization aligns its authoritative Markdown. That normalization preserves existing planning authority and does not require an unrelated product or delivery change. Always confirm exact scripts and input expectations in the active repository before running or documenting them for another edition.
142
+
143
+ ## Hand off work without implying implementation
144
+
145
+ Once the planning authority is coherent and implementation is approved, route the next task deliberately:
146
+
147
+ - unresolved domain identity or boundary → `cabloy-domain-planning`
148
+ - approved backend increment → `cabloy-backend-scaffold`
149
+ - approved frontend increment → `cabloy-frontend-scaffold`
150
+ - contract synchronization or generated-consumer drift → `cabloy-contract-loop`
151
+ - an approved bounded WBS increment → [Playbook: Execute an Approved Cabloy Specification Increment](/ai/playbook-spec-execution)
152
+
153
+ Do not make code changes, run initialization or database-reset workflows, deploy, operate a provider, or claim implementation or verification merely because planning records now exist.
154
+
155
+ For the division of responsibility between public docs, skills, repository specs, and internal rationale, read [Docs, Skills, Rules, and CLI Mapping](/ai/docs-skills-rules-mapping).
@@ -8,10 +8,11 @@ Check the root repository signals first:
8
8
 
9
9
  - `package.json`
10
10
  - edition marker files such as `__CABLOY_BASIC__` or `__CABLOY_START__`
11
- - an established internal-documentation home, when present
11
+ - `repo-docs-internal/`
12
+ - `repo-specs/` when the task concerns a suite plan, WBS increment, acceptance record, or evidence
12
13
  - root `.claude/` assets
13
14
 
14
- These surfaces tell the agent which repo it is in and which scripts are canonical. Inspect an internal-documentation home only when the active repository actually provides one.
15
+ These surfaces tell the agent which repo it is in and which scripts are canonical. Inspect relevant `repo-docs-internal/` records as supporting context rather than as a gate to workflow guidance.
15
16
 
16
17
  ## 2. Prefer framework entrypoints over scattered examples
17
18
 
@@ -27,11 +28,14 @@ For frontend workflows:
27
28
 
28
29
  This is more reliable than copying old file structures from examples without understanding the command surface that created them.
29
30
 
30
- ## 3. Use public docs and optional internal notes for different purposes
31
+ ## 3. Use public docs, suite records, and internal notes for different purposes
31
32
 
32
33
  - use `repo-docs/` to explain how people and agents should work
33
- - when an established internal-documentation home exists, use it for maintainer rationale
34
- - when it does not exist, continue from public docs, rules, skills, source, and tests; do not create a new documentation home implicitly
34
+ - use `repo-specs/<suite>/` for suite-local product, technical, delivery, ATP, progress, ADR, and observed-evidence authority
35
+ - use `repo-docs-internal/` for supporting maintainer rationale
36
+ - continue from public docs, rules, skills, source, and tests when a specific internal record is unavailable or irrelevant; do not create a replacement document implicitly
37
+
38
+ For planning work, read the suite README, PRD, SRS, WBS, test plan, and progress records in the order appropriate to the task. `cabloy-spec-generation` maintains planning authority; `cabloy-spec-execution` acts only on a confirmed, bounded WBS increment. Both require active-source and edition discovery before topology or command claims.
35
39
 
36
40
  ## 4. Treat edition detection as mandatory for UI-sensitive work
37
41
 
@@ -8,7 +8,7 @@ Use the root `CLAUDE.md` for concise, durable operational guidance such as:
8
8
 
9
9
  - how the monorepo is organized
10
10
  - where public docs live
11
- - whether an established internal-documentation home is available
11
+ - where `repo-docs-internal/` holds supporting maintainer rationale
12
12
  - which command entrypoints are preferred
13
13
  - why edition detection is mandatory before UI-sensitive guidance or project-creation assumptions
14
14
 
@@ -26,4 +26,4 @@ Use Claude settings for permissions and execution environment, not as the primar
26
26
 
27
27
  ## Documentation boundary
28
28
 
29
- If a rule is important for people and agents to understand, it probably belongs in public docs too. When an established internal-documentation home exists, it may hold maintainer rationale rather than user-facing workflow. Do not infer or create such a home from edition identity alone.
29
+ If a rule is important for people and agents to understand, it probably belongs in public docs too. `repo-docs-internal/` holds supporting maintainer rationale rather than user-facing workflow; individual records may vary by edition.
@@ -42,8 +42,12 @@ Current examples include:
42
42
 
43
43
  - `cabloy-workflow` for choosing the correct Cabloy work path before implementation
44
44
  - `cabloy-domain-planning` for proposing and confirming providerId, suite, and initial module names before scaffolding a new business domain
45
+ - `cabloy-spec-generation` for creating or maintaining suite-local planning authority, traceability, and derived planning views before implementation
46
+ - `cabloy-spec-execution` for coordinating one confirmed WBS increment through specialist implementation, evidence, and derived progress updates
45
47
  - `cabloy-contract-loop` for backend/frontend contract regeneration and drift diagnosis
46
48
  - `cabloy-resource-field-update` for updating an existing backend resource field thread
47
49
  - `cabloy-module-removal` for removing a backend, frontend, or fullstack module cleanly, including generated-runtime cleanup, stale-residue recovery, and verification
48
50
 
51
+ The specification workflows show the same boundary: [Playbook: Plan a Cabloy Suite Specification](/ai/playbook-spec-generation) and [Playbook: Execute an Approved Cabloy Specification Increment](/ai/playbook-spec-execution) explain the durable public workflow, while the skills retain the branching, confirmation gates, specialist routing, and evidence protocol.
52
+
49
53
  The module-removal workflow is a good example of why skills belong in `.claude/skills/` instead of `CLAUDE.md`: the task needs branching, cleanup order, recovery guidance for generated runtime directories such as `vona/.vona` and `zova/.zova`, and a verification checklist that would be too large for a short repo-wide rule.
@@ -201,4 +201,4 @@ Read these pages together:
201
201
  - [Global Bean Lookup](/ai/global-bean-lookup)
202
202
  - [Docs, Skills, Rules, and CLI Mapping](/ai/docs-skills-rules-mapping)
203
203
 
204
- For maintainer-level rationale, consult an established internal-documentation home when the active repository provides one. The public guidance above is the complete shared operational rule.
204
+ For maintainer-level rationale, consult relevant records in `repo-docs-internal/`. The public guidance above is the complete shared operational rule.
@@ -19,7 +19,7 @@ For contributor and automation workflows in this repository, prefer this order:
19
19
  1. inspect the root `package.json` and `npm run vona` entrypoint
20
20
  2. inspect Vona CLI command families such as `create:*`, `init:*`, `tools:*`, and `bin:*`
21
21
  3. inspect the current module or suite layout before creating new files manually
22
- 4. use public docs for user-facing and agent-facing guidance; consult an established internal-documentation home only when the active repository provides one for maintainer rationale
22
+ 4. use public docs for user-facing and agent-facing guidance; consult relevant `repo-docs-internal/` records for supporting maintainer rationale
23
23
 
24
24
  ## Backend reading paths
25
25
 
@@ -87,7 +87,8 @@ export class ModelStudent extends BeanModelBase {
87
87
  return res ?? null;
88
88
  },
89
89
  meta: {
90
- disableSuspenseOnInit: true,
90
+ // The Summary dialog renders query errors itself.
91
+ disableErrorEffect: true,
91
92
  },
92
93
  });
93
94
  }
@@ -121,14 +122,40 @@ const modelStudent = (await ctx.bean._getBean(
121
122
  true,
122
123
  )) as ModelStudent;
123
124
  const querySummary = modelStudent.summary(id);
125
+ await querySummary.suspense();
124
126
 
125
- await querySummary.refetch({ bypassPersister: true });
126
127
  $host.$appModal.dialog({
127
- slotDefault: () => <ZMarkdownHtml html={querySummary.data?.descriptionHtml ?? ''} />,
128
+ slotDefault: () => {
129
+ const hasData = querySummary.data !== undefined;
130
+ const isLoading = !hasData && (querySummary.isPending || querySummary.isFetching);
131
+ const error = querySummary.error;
132
+
133
+ return (
134
+ <>
135
+ {hasData && error && (
136
+ <div class="alert alert-warning" role="alert">
137
+ <span>{this.scope.locale.SummaryRefreshFailed()}</span>
138
+ </div>
139
+ )}
140
+ {error && (
141
+ <div class="alert alert-error" role="alert">
142
+ <span>{error.message}</span>
143
+ </div>
144
+ )}
145
+ {hasData ? (
146
+ <ZMarkdownHtml html={querySummary.data?.descriptionHtml ?? ''} />
147
+ ) : isLoading ? (
148
+ <div role="status">Loading...</div>
149
+ ) : undefined}
150
+ </>
151
+ );
152
+ },
128
153
  });
129
154
  ```
130
155
 
131
- `refetch({ bypassPersister: true })` is useful when this interaction needs an API-fresh result without restoring or scheduling a persistence save through the persister for that fetch. The successful result still updates the model-owned in-memory query, and the dialog remains bound to `querySummary.data`, so the query remains the source of its ongoing render state rather than transferring ownership to an awaited-result snapshot. The option affects only this fetch; normal query cancellation and in-flight deduplication rules still apply. It is not a force-new-request option: when an existing fetch is reused by TanStack Query, that fetch's semantics remain in effect. The bypassed fetch itself does not intentionally replace an existing persisted value; an already queued ordinary persistence callback is a separate operation and is not automatically cancelled. Use static `meta.persister: false` only when persistence should be disabled for the query generally.
156
+ Opening this Summary dialog is an interaction readiness boundary, so the handler awaits the existing model-owned query with `await querySummary.suspense()` before creating the dialog. That wait follows normal query cache, staleness, error, persistence, and deduplication semantics; it is not an unconditional API-fresh request. After opening, the dialog remains bound to reactive query state rather than an awaited one-shot result, so later query updates remain visible.
157
+
158
+ Use `data !== undefined` as the availability boundary. Retained data plus `error` renders two distinct messages while preserving the content: a non-blocking localized refresh-failure warning explains that the content may be outdated, and `error.message` explains the concrete failed fetch. No data plus `error` renders only the concrete fetch error. This is persisted-cache-first stale-while-revalidate UI, not an API-fresh orchestration decision. Whether restore and follow-up revalidation occur depends on data availability, persister configuration, and staleness.
132
159
 
133
160
  ### Avoid
134
161
 
@@ -161,7 +188,8 @@ summary(id: TableIdentity) {
161
188
  return res ?? null;
162
189
  },
163
190
  meta: {
164
- disableSuspenseOnInit: true,
191
+ // The Summary dialog renders query errors itself.
192
+ disableErrorEffect: true,
165
193
  },
166
194
  });
167
195
  }
@@ -242,6 +270,8 @@ deleteForce(id: TableIdentity) {
242
270
  - item/list invalidation remains centralized
243
271
  - the business-facing model exposes semantic actions without competing for cache ownership
244
272
 
273
+ `mutationItem(...)` awaits its standard consistency work before mutation completion: it invalidates matching active `select` queries unless `invalidateSelect: false`, then invalidates matching active queries under the row's item root, and only then invokes and awaits the optional custom `onSuccess`. This keeps `mutateAsync()` aligned with active resource refreshes. `invalidateSelect: false` skips only the default select invalidation; item-root invalidation remains automatic.
274
+
245
275
  ## Recipe 5: customize invalidation for a special mutation
246
276
 
247
277
  ### Use this when
@@ -261,7 +291,6 @@ publish(id: TableIdentity) {
261
291
  },
262
292
  onSuccess: async () => {
263
293
  await this.$$modelResource.$invalidateQueries({ queryKey: ['select'] });
264
- await this.$$modelResource.$invalidateQueries({ queryKey: ['item', id] });
265
294
  await this.$$modelResource.$invalidateQueries({ queryKey: ['select', 'dashboard'] });
266
295
  },
267
296
  });
@@ -271,7 +300,7 @@ publish(id: TableIdentity) {
271
300
  ### Why this works well
272
301
 
273
302
  - the existing resource-owner remains the source of truth for consistency rules
274
- - special cache dependencies stay explicit
303
+ - the automatic item-root invalidation completes before this callback adds the special list dependencies
275
304
  - pages do not need to remember hidden follow-up refetch rules
276
305
 
277
306
  ### Avoid
@@ -412,6 +441,8 @@ batchArchive(ids: TableIdentity[]) {
412
441
  - list invalidation policy remains visible
413
442
  - cache ownership still stays with the existing resource-owner even when row-level helpers are not the right fit
414
443
 
444
+ This uses raw `$useMutationData(...)` because a batch action affects multiple rows rather than the one `id` accepted by `mutationItem(...)`. It does not inherit `mutationItem(...)`'s automatic item-root invalidation or sequencing, so define and await the necessary list and per-item invalidations explicitly.
445
+
415
446
  ## Recipe 10: keep generic blocks working while adding resource semantics
416
447
 
417
448
  ### Use this when
@@ -129,7 +129,8 @@ export class ModelStudent extends BeanModelBase {
129
129
  return res ?? null;
130
130
  },
131
131
  meta: {
132
- disableSuspenseOnInit: true,
132
+ // The Summary dialog renders query errors itself.
133
+ disableErrorEffect: true,
133
134
  },
134
135
  });
135
136
  }
@@ -116,7 +116,7 @@ Recommended order:
116
116
 
117
117
  The public router-tabs docs explain the shared frontend mechanism and how to use it.
118
118
 
119
- For maintainer-only design boundaries, maintenance invariants, and refactor safety rules, consult an established internal-documentation home when the active repository provides one. The public mechanism, layout, route-meta, and Admin/Web comparison guides remain the shared implementation baseline.
119
+ For maintainer-only design boundaries, maintenance invariants, and refactor safety rules, consult relevant `repo-docs-internal/` records. The public mechanism, layout, route-meta, and Admin/Web comparison guides remain the shared implementation baseline.
120
120
 
121
121
  ## See also
122
122
 
@@ -284,6 +284,8 @@ A query established during render remains the owner of its ongoing state. Render
284
284
 
285
285
  An interaction or orchestration boundary may still await `query.refetch()` when it needs one result to decide whether to continue a command, navigate, show a notification, or open a dialog. That result is local to the current sequence; it does not transfer query ownership to the controller or render path.
286
286
 
287
+ When a query-backed dialog needs readiness before it opens, await the existing query's `suspense()` instead. This follows normal query cache, staleness, error, and deduplication semantics; it does not necessarily force an API-fresh request. After the dialog opens, continue to render from the query wrapper rather than the awaited result.
288
+
287
289
  Do not copy an awaited `refetch()` result into a second long-lived controller/render state that drives an open dialog or persistent component. If the UI remains mounted and displays query-backed data, bind it to `query.data` or a model-derived reactive surface so later refetches and model updates remain visible.
288
290
 
289
291
  ### Per-fetch persistence bypass
@@ -305,22 +307,53 @@ await query.refetch({ bypassPersister: true });
305
307
 
306
308
  This option is not a force-new-request flag. Cancellation, `cancelRefetch`, and in-flight deduplication continue to follow TanStack Query semantics. If an existing fetch is reused, its already-established fetch semantics remain in effect. The bypassed fetch itself does not intentionally replace an existing persisted value; an already queued ordinary persistence callback is a separate operation and is not automatically cancelled.
307
309
 
310
+ When the current interaction or polling iteration must make an immediate decision from its API-oriented fetch, consume the awaited result rather than rereading `query.data`:
311
+
312
+ ```ts
313
+ const result = await queryPaymentSession.refetch({
314
+ bypassPersister: true,
315
+ });
316
+ const session = result.data;
317
+
318
+ if (session?.state === 'succeeded') {
319
+ // Decide this iteration from this fetch result.
320
+ }
321
+ ```
322
+
323
+ `query.data` remains the reactive, long-lived surface for rendering and subsequent updates. `result.data` is the result for this one awaited sequence. Keeping those roles separate prevents a controller from treating ongoing render state as the local result variable for a command. The result represents this fetch's response; it does not guarantee that no later server-side state transition occurs, and normal TanStack Query reuse semantics still apply.
324
+
308
325
  This is different from static `meta.persister: false`: the static option disables persistence for the query generally, while `bypassPersister: true` opts out only for one fetch.
309
326
 
310
- For example, an interaction can request a fresh summary and then open a dialog while the dialog remains bound to the query-owned state:
327
+ By contrast, a summary dialog can deliberately use persisted-cache-first behavior while remaining bound to query-owned state:
311
328
 
312
329
  ```ts
313
330
  const querySummary = modelStudent.summary(id);
314
- await querySummary.refetch({ bypassPersister: true });
331
+ await querySummary.suspense();
315
332
 
316
333
  $host.$appModal.dialog({
317
- slotDefault: () => (
318
- <ZMarkdownHtml html={querySummary.data?.descriptionHtml ?? ''} />
319
- ),
334
+ slotDefault: () => {
335
+ const hasData = querySummary.data !== undefined;
336
+ const isLoading = !hasData && (querySummary.isPending || querySummary.isFetching);
337
+ const error = querySummary.error;
338
+
339
+ return (
340
+ <>
341
+ {hasData && error && <SummaryRefreshWarning />}
342
+ {error && <SummaryFetchError error={error} />}
343
+ {hasData ? (
344
+ <ZMarkdownHtml html={querySummary.data?.descriptionHtml ?? ''} />
345
+ ) : isLoading ? (
346
+ <SummaryLoading />
347
+ ) : undefined}
348
+ </>
349
+ );
350
+ },
320
351
  });
321
352
  ```
322
353
 
323
- The awaited result may coordinate the current interaction, but ongoing rendering should continue to read `querySummary.data`.
354
+ This Summary interaction deliberately awaits `querySummary.suspense()` before opening the dialog. It therefore has a query-readiness boundary, but does not force an API-fresh request: the wait still follows normal query cache, staleness, error, persistence, and deduplication semantics. The open dialog reads every later transition through `querySummary.data` and its query status rather than taking ownership of an awaited one-shot result.
355
+
356
+ Treat `data !== undefined` as the availability boundary. Retained data plus `error` has two separate user-facing meanings: render a non-blocking refresh-failure warning to explain that the retained content may be outdated, render the concrete `error.message` through `SummaryFetchError`, and keep the content visible. With no data plus `error`, render only the concrete fetch error. This is persisted-cache-first stale-while-revalidate UI, not an API-fresh orchestration request. Restore and follow-up revalidation depend on data availability, persister configuration, and staleness.
324
357
 
325
358
  ## Practical rule 7: derive render-time state once per render when possible
326
359
 
@@ -6,9 +6,12 @@ This monorepo is organized around a small set of stable top-level areas.
6
6
 
7
7
  - `package.json` — shared scripts and release entrypoints
8
8
  - `lerna.json` — package topology
9
- - an established internal-documentation home, when present — edition-local maintainer notes and ADRs
9
+ - `repo-docs-internal/` — edition-local maintainer notes and ADRs
10
10
  - `.claude/` — Claude commands, skills, and local settings
11
11
  - `repo-docs/` — unified public docs
12
+ - `repo-specs/` — suite-local product, technical, delivery, ATP, progress, observed-evidence, and ADR authority
13
+
14
+ `repo-specs/` is distinct from `repo-docs/`, which explains reusable public guidance, `.claude/`, which contains executable workflow behavior, and `repo-docs-internal/`, which preserves supporting maintainer rationale. For the public planning workflow, see [Playbook: Plan a Cabloy Suite Specification](/ai/playbook-spec-generation).
12
15
 
13
16
  ## Backend side
14
17
 
@@ -42,6 +42,31 @@ Cabloy Basic exposes these shared root scripts:
42
42
 
43
43
  `npm run init` prepares all Cabloy Basic SSR and REST artifacts with `npm run build:zova:all`, which sequentially builds the Basic and Commerce flavor batches before Vona initialization. Use `build:zova` or `build:zova:commerce` for focused artifact refreshes; use `build:zova:all` only when every shipped Basic flavor must be prepared.
44
44
 
45
+ ## Specification planning and derived charts
46
+
47
+ The current Cabloy Basic root scripts also expose:
48
+
49
+ ```bash
50
+ npm run test:spec-charts
51
+ npm run spec:charts -- <suite>
52
+ npm run spec:charts:check -- <suite>
53
+ ```
54
+
55
+ `spec:charts` refreshes the generated Gantt and burndown SVG views for a chart-compatible `repo-specs/<suite>/` record. `spec:charts:check` validates the supported input contract and detects stale generated views; `test:spec-charts` runs the chart-tool test suite.
56
+
57
+ ### Chart input contract
58
+
59
+ The generator consumes `README.md`, `pdp-wbs.md`, `test-plan.md`, and `progress.md`. The supported Markdown format includes:
60
+
61
+ - formal `### Phase <number>:` and `#### WBS-...:` headings in the WBS, with supported dependency labels
62
+ - formally defined `ATP-*` scenarios in the test plan for every ATP reference used by a WBS task
63
+ - one progress row for each WBS item, with the WBS ID in the first cell and its supported status in the second cell
64
+ - a README whose current title and language should be reflected by regenerated chart output
65
+
66
+ A legacy suite with a different WBS or progress-table layout is not chart-compatible until a deliberate record-format normalization aligns its authoritative Markdown with this input contract. Format normalization must preserve the existing planning authority; it does not require an unrelated product or delivery change.
67
+
68
+ These commands do not create planning authority, implement a WBS task, execute an ATP, produce acceptance evidence, or replace traceability/status review. Confirm the active root `package.json` and script input expectations before assuming equivalent behavior in Cabloy Start or another repository.
69
+
45
70
  ## Cabloy Start entrypoints
46
71
 
47
72
  Cabloy Start exposes the equivalent Start repository surface: