name: cabloy-contract-loop description: Use this skill whenever a Cabloy task crosses the Vona-to-Zova contract boundary: backend DTO, controller, validation, entity, inferred DTO, or OpenAPI changes that should drive SDK, schema, api, model, or rest-output regeneration, or stale generated frontend consumers that may be out of sync with backend truth. Trigger for requests about stale home-api output, OpenAPI regeneration, whether to regenerate instead of hand-patching types, or how to verify the Cabloy Basic or Cabloy Start contract loop end to end. Prefer it when the main problem is backend/frontend sync or diagnosis, not initial backend scaffolding or frontend page/component scaffolding.
Cabloy Contract Loop
Use this skill when a backend contract change needs to be reflected in frontend consumers, when frontend-owned metadata or resources need to be reflected back into backend consumers, or when either side appears stale and you need to diagnose where drift actually lives.
Read the public Contract Loop Playbook for the canonical bidirectional model. This skill is the branching orchestration guide.
Important recovery note for stale local file consumers
When generated .zova-rest output or other generated consumer artifacts already contain the expected new keys or types but Vona still behaves as if old consumer types are installed, treat that first as a local file-dependency installation problem rather than a source-editing problem.
This includes the reverse fullstack direction where newly added frontend resources such as custom renderers are later consumed by backend metadata.
In that situation:
- run the normal sync or regeneration flow first
- if Vona consumes newly added or changed Zova Admin render/action/metadata in Cabloy Basic, run
npm run build:zova:adminfrom the repo root before anything else - otherwise, if the change only affects flavor-built REST/type output, rebuild the relevant Zova flavor output first
- run
deps:vona - if stale behavior remains, rebuild
vona/node_modulesand reinstall dependencies
Do not keep debugging source-level contract or renderer changes until the local file-package installation state is known to be healthy.
Current safeguard behavior in this repo
- there is no contract-loop pre-commit gate in the current repo workflow
- the active safeguard lives in the Claude
PostToolUsehook configured in.claude/settings.json - for high-confidence reverse-chain source edits on the Zova side, the hook auto-runs
npm run build:zova:adminand thennpm run deps:vona - forward-chain detections remain reminder-only, so backend contract changes still require deliberate regeneration and verification
- consumer-side reverse signals remain reminder-only, so do not assume every reverse-chain case auto-syncs itself
Goals
- detect whether the active repository is Cabloy Basic or Cabloy Start
- classify whether the task truly crosses the backend/frontend contract boundary
- route the task into one of four modes: forward chain, reverse chain, consumer drift diagnosis, or local dependency drift recovery
- keep the workflow contract-first instead of hand-patching generated frontend types or services
- prefer CLI-first regeneration paths on both Vona and Zova sides
- finish with end-to-end verification guidance that checks both contract production and consumption
Step 1: Detect repo, edition, and branch
Check the repository root for these marker files:
__CABLOY_BASIC____CABLOY_START__
Interpretation:
__CABLOY_BASIC__present → this is Cabloy Basic__CABLOY_START__present → this is Cabloy Start- neither present → inspect nearby scripts and ask before making edition-specific assumptions
Then classify whether the task is really a contract-loop task.
These four modes are shared across Cabloy Basic and Cabloy Start. Edition detection chooses the operational branch, but does not change the core contract-loop model.
Use this skill in four common entry modes.
Mode A: forward chain
The user already changed or plans to change backend contract surfaces such as:
- controller request or response shape
- DTO shape
- entity field shape that feeds API-facing contracts
- validation rules
- OpenAPI metadata
- inferred DTO or ORM DTO output that affects API consumers
Mode B: reverse chain
The user changed or plans to change frontend-owned resources or metadata that backend-side tooling or metadata will later consume, such as:
- routes
- components
- icons
- custom form-field resources
- custom table-cell resources
- generated frontend metadata that backend
ZovaRender.*(...)references depend on
Mode C: consumer drift diagnosis
The user reports symptoms on the frontend side such as:
- stale SDK types
- stale schema-driven UI behavior
- API/model consumers no longer matching backend reality
- hand-patched frontend types that seem to drift from backend truth
In this mode, first diagnose whether the visible stale behavior comes from skipped regeneration, a wrong source-of-truth edit, or a stale generated consumer.
Mode D: local dependency drift recovery
Use this mode when generated artifacts already contain the expected keys, types, or resources, but installed local file dependencies still behave stale after the normal sync flow.
If the task is only backend scaffolding or only frontend scaffolding, the more specialized scaffold skills may be the better primary choice.
Step 2: Start from the contract source of truth
Inspect these surfaces before proposing workflow:
- the repository or workspace
package.jsonthat owns the scripts - backend contract-defining code in Vona
npm run zova- frontend generation or consumption path in Zova
- relevant docs in
cabloy-docs/fullstack/,cabloy-docs/backend/, andcabloy-docs/frontend/
For deeper reference material, read:
references/contract-loop-map.mdreferences/verification-checklist.mdreferences/resource-custom-state-pattern.md
Step 3: Identify the contract source of truth deliberately
In Cabloy, the backend is often the source of truth for the contract. Treat that as the default unless the codebase clearly shows a frontend-owned artifact that the reverse chain should hand back into backend consumers.
If this is the forward chain
Start with the backend side and update the contract deliberately.
Typical backend layers to inspect or change include:
- controller action signatures and annotations
- DTO classes
- entity field metadata
- validation rules and
vhelpers - inferred DTO generation paths
- OpenAPI configuration or metadata annotations
The key rule is:
- do not patch frontend consumers first if the backend contract is the real source of truth
If this is the reverse chain
Start with the frontend-owned resource or metadata that backend consumers later depend on.
Typical frontend layers to inspect or change include:
- routes
- components
- icons
- custom form-field resources
- custom table-cell resources
- generated metadata that backend
ZovaRender.*(...)references depend on
The key rule is:
- do not treat this as frontend-only cleanup if backend consumers depend on the generated handoff
If this is consumer drift diagnosis
Do not assume the visible stale behavior identifies the wrong layer automatically.
Instead:
- inspect what artifact looks stale
- identify whether that artifact is generated, schema-driven, or hand-authored
- inspect the source layer that should feed it
- only then decide whether the fix is regeneration, source correction, consumer alignment, or a genuine bug
If this is local dependency drift recovery
Only enter this branch after the source layer and generated handoff are already known to be correct.
Step 4: Verify backend contract output before touching frontend consumers
Before regenerating frontend artifacts, confirm the backend-side contract is actually correct.
That may include:
- reviewing controller return contracts
- confirming DTO and validation alignment
- checking Swagger/OpenAPI output
- confirming that the changed endpoint or schema now reflects the intended contract
- if local OpenAPI generation depends on a running Swagger source, starting the backend service first — in Cabloy Basic,
npm run devis the normal path and exposeshttp://localhost:7102/swagger/json?version=V31
If the backend contract output is wrong, frontend regeneration will only spread the mistake.
Step 5: Choose the right frontend regeneration path
Once the backend contract is correct, decide how the frontend should consume it.
Path A: OpenAPI / SDK regeneration
Use this when the frontend consumes generated API contracts.
Typical Zova commands include:
npm run zova :openapi:config ...npm run zova :openapi:generate ...
Preflight reminder:
- if
:openapi:generatereads from a local Swagger endpoint, do not assume the generator itself is broken when fetch fails - first start the backend service, typically with
npm run dev, and confirmhttp://localhost:7102/swagger/json?version=V31is reachable
When the target is a module-local SDK, constrain openapi.config.ts with operations.match unless the module intentionally owns a broad API surface. This prevents unrelated APIs from being generated into the module.
Path B: REST/type generation by flavor
Use the edition-specific Zova REST/type build path when the workflow depends on the built flavor outputs.
Typical examples in Cabloy Basic include:
cd zova && npm run build:rest:cabloyBasicAdmincd zova && npm run build:rest:cabloyBasicWeb
Important Cabloy Basic reverse-sync rule:
- if Vona consumes newly added or changed Zova Admin render/action/metadata, do not stop at
build:rest:cabloyBasicAdmin - run
npm run build:zova:adminfrom the repo root instead, then runnpm run deps:vona - treat this as a JS-bundle-plus-rest-output handoff, not a rest-types-only refresh
- the current repo safeguard may auto-run those two commands for high-confidence Zova reverse-source edits, but only as a convenience layer on top of the contract-loop model
- if the change was consumer-side, low-confidence, cross-edition, or happened outside the Claude hook path, run the reverse sync flow deliberately yourself
- prefer visible proof under
zova/src/**/.metadata/**when it is available; if the effective handoff only appears in.zova-rest, treat the safeguard as conservative reminder/auto-sync assistance rather than strict proof
For Cabloy Start, verify the exact Start-specific flavor names, paths, SSR site baselines, and project assets in the licensed Start repo.
Path C: Downstream frontend alignment
After generation, inspect whether the frontend still needs follow-up in:
- API services
- model-managed remote state
- schema-driven UI
- page or component assumptions
Keep frontend follow-up thin:
- use thin semantic model facades over generated consumers instead of re-declaring the contract
- if a custom endpoint still belongs to an existing resource, prefer one resource-state owner instead of letting a module-local model create a second cache tree
Reuse the resource-owned custom state pattern in references/resource-custom-state-pattern.md.
Step 6: Keep edition-aware differences explicit
The collaboration model is shared across Basic and Start, but the operational details may differ.
Especially verify:
- active repo marker
- affected frontend flavor
- whether the change affects Admin, Web, or both
- whether the generated output path is edition-specific
Do not silently reuse Basic-specific examples in Start workflows.
Step 7: End-to-end verification
A fullstack contract loop is not done until both sides are checked.
Backend-side verification
Typical checks may include:
- controller-level tests
- OpenAPI inspection
npm run testnpm run tscnpm run build
Frontend-side verification
Typical checks may include:
- SDK or metadata regeneration success
npm run tsc:zovanpm run build:zova- flavor-specific or route-specific checks
- schema-driven consumer alignment
Step 8: Response pattern
When helpful, structure the response around these points:
- detected edition
- why this is a contract-loop task
- backend source-of-truth layer to change first
- frontend regeneration path to run second
- edition-specific operational notes
- end-to-end verification steps
Keep the response practical. The value of this skill is to prevent contract drift between Vona and Zova by guiding the user through the right backend-first, regeneration-second, verification-third workflow.