# NexusCRM Agent Guide

One fact, one owner, one source of truth, one effective read path.
`AGENTS.md` is the canonical file; `CLAUDE.md` is a relative symlink to it.
Keep this root guide under 200 lines; put detailed procedures in linked docs.

## Work to the requested outcome

- Treat requests for action as authorization to do the work. Carry the scoped
  outcome through implementation, relevant verification, and the requested
  delivery; do not stop at a plan or an offer to continue.
- Use conversation context and reasonable judgment for reversible choices.
  Ask only when a consequential ambiguity or missing authorization blocks the
  next action. Prepare the authorized work before requesting a final decision;
  do not repeatedly ask for permission already given.
- Follow explicit user direction over optional skill guidelines, subject to
  governing system/developer constraints. If an instruction or approval gate
  blocks work, identify its exact source and reason; distinguish a written
  requirement from your interpretation. Do not invent approval requirements.
- Read current code before designing changes. Before changing an owner,
  registry, compatibility surface, or shared read/write path, map its current
  producers and consumers. Historical issues and docs are context, not proof.
- Recheck the problem and owning boundary when evidence contradicts the plan.
  Keep related discoveries separate unless the requested outcome depends on
  them. Prefer existing mechanisms and remove replaced paths in the same change.
- Preserve user changes. Use an isolated worktree when needed. Do not broaden
  a task into unrelated cleanup or deployment.
- Report the outcome, relevant evidence and remaining limits in plain language.
  Keep progress updates concise; distinguish implemented, tested and proposed.

## Repository and ownership routing

NexusCRM is a public-core CRM platform with Go engines, React runtime and TiDB.
A clean startup must not depend on tenant metadata, data or identities.
A repository is a release boundary; a Go module is an architecture boundary.

| Concern | Owner |
|---|---|
| Metadata/schema; records/query; automation/Flow; analytics | Core `nexuscrm-metadata`, `nexuscrm-records`, `nexuscrm-automation`, `nexuscrm-analytics` |
| Permissions/auth; persistence/storage/DB | Core `nexuscrm-permissions`, `nexuscrm-auth`, `nexuscrm-persistence`, `nexuscrm-storage`, `nexuscrm-db` |
| Audit/events/outbound; workers; files | Core `nexuscrm-audit`, `nexuscrm-events`, `nexuscrm-outbound`, `nexuscrm-worker`, `nexuscrm-files` |
| Runtime process assembly; React host/SDK; boundary gate | Core `backend`, `frontend/src/host`, `frontend/src/host-sdk`, `tools/boundarygate` |
| Neutral contract/IR and separately versioned wire module | `nexuscrm-contract` |
| Pack install/upgrade/migrate/verify/drift/bootstrap | `nexuscrm-controlplane` |
| Transport, dialect binding, middleware, Runtime gRPC policy | `nexuscrm-api-host` |
| Integration, webhooks/callouts, credentials, connector registry | `nexuscrm-connectors` |
| Salesforce grammar/routes, official defaults, app frontend | L1 `nexuscrm-app-packs` |
| Tenant overlays, final assembly and deployment | L2 delivery repository |

Read dependency versions from current `go.mod`/`go.work` and lockfiles; do not
copy pins into this guide. Full topology and phase dispositions are in
[repo-split.md](docs/architecture/repo-split.md).

- Dependencies point `L2 → L1 → L0`; L0 never imports L1 or tenant delivery.
- The contract semantic root uses Go stdlib only; it excludes SQL, HTTP,
  protobuf and gRPC. Generated wire code has a separate module boundary.
- Controlplane, API-host and Connectors must not import `backend`. Backend
  consumes published modules by version pin; no local `replace` on `main`.
- The mutually recursive core engine modules remain one modular monolith.
  This does not authorize restoring the retired monolith serving process.
- The closed L0-A…L0-F roadmap does not prove all semantic cleanup is complete.
  Use its current boundary ledger; do not reopen/reorder that sequence silently.
  Security-standalone and formula-last ordering remain normative there.
- The issue-tracker conformance fixture in app-packs is sealed and CI-only;
  it is not a second shipped product, pack, dialect or frontend.

## Layer and public-core invariants

Use [l0-l1-standard.md](docs/design/l0-l1-standard.md) and its ordered T0→T5
ownership tests for layer decisions. Cite that standard; the summary below does
not amend the metamodel floor.

- L0 owns generic engines, interpreters and seams. L1 owns product grammar and
  shipped defaults. L2 owns administrator-authored configuration; L3 owns
  user-authored records. Packaging alone does not determine ownership.
- Reuse a Salesforce v63-modeled fact before introducing a substitute:
  Salesforce primitive → existing platform primitive → generic extension →
  new primitive. Platform code interprets metadata; it does not author tenant
  business behavior.
- In generic engines/platform Go or TS and L1 defaults, do not hardcode concrete
  tenant `__c` fields/objects, Profile IDs/names, RecordType or ApprovalProcess
  DeveloperNames, business statuses/picklists, tenant SQL, or SObject branches.
  Tests/fixtures are exempt from these code-pattern restrictions.
- Do not place tenant payload, legal-entity/product/customer names, tenant
  identities or bootstrap rows in public-core. Generic overlay/install tools
  are substrate, not a home for checked-in tenant configuration. Clean old
  tenant residue through a one-time migration rather than permanent branches.
- Use FieldPermissions and ValidationRule metadata, not code allowlists. Do not
  duplicate SharingModel, RecordType, field/object shape, or effective access
  decisions. Derived shape belongs to MetadataService, not a feature registry.
- Infrastructure fields, `_System_*` schema, generic suffix handling, standard
  permission keys, and secret-hardening lists may be generic substrate. They
  do not exempt a specific behavior from the ownership tests.
- Before adding a registry/cache, identify its fact, authoring surface, sole
  read path, replaced path and fail-closed conflict behavior. A cache is derived
  and cannot compete with its fact owner.
- For authority cutovers: either remove the wrong-shape piece and track its
  prerequisite, or switch the complete consumer closure and remove the old
  authority in the same PR. Do not land a second authority for later cleanup.
- Use `scripts/scan-public-core-boundary.sh` for relevant changes. Explain or
  remove non-test hits; enforce non-negotiable rules in hooks/CI, not prose alone.

## Online configuration is independent of Catalog publication

UI-editable configuration, including equivalent API/import writes, must save,
activate and become visible without Catalog/AppRelease refresh, upgrade or
redeployment. Each domain owns its current facts and versions. Catalog owns
package/install/deployment and capability admission; executable app installation
remains a release operation.

Preserve security coordination, physical schema preparation, request stability
and durable definition retention. Do not introduce a Catalog/live-metadata
fallback. Existing coupling is a migration finding, not a design requirement.
Read the [normative boundary and consumer audit](docs/design/configuration-and-execution-lifecycle.md)
before changing these paths. Layout, PermissionAuthoring and Navigation keep
their existing owners; Schema must not recreate their writes.

## Product and runtime contracts

- Salesforce v63.0 is the external product oracle. Read the
  [API contract](docs/design/salesforce-v63-api-contract.md) before changing a
  public handler, dialect projection or UI API endpoint. Preserve wire shape,
  error mapping, object/field and permission semantics. Do not shrink the
  frontend contract to hide a backend gap; make any delta explicit and verified.
- `$User`, `$Profile` and `$UserRole` come from the JWT-backed UserSession.
  Build globals via `backend/pkg/formula.BuildFormulaUserContext`; no DB reads
  or mid-session refresh of session-bound IDs/names. Admin writes revoke the
  session. See [formula context](docs/design/formula-session-context.md).
- Automation is metadata-first: Flow, formula/expression and generic invocable
  capabilities with authorization/lifecycle/observability. Do not clone Apex or
  embed tenant logic in Go. Classify parity as implemented, generic-extension
  path, unsupported gap or out of target.
- Follow [current serving/authoring owners](docs/design/metadata-authoring-current-paths.md)
  rather than old route declarations. Internal engine methods do not prove a
  reachable authoring capability.

## Verification, review and delivery

- Define verification around changed invariants, owners, entrypoints, topology,
  concurrency and failure windows. Use static/compile checks, then relevant
  owner batches and producer-to-consumer journeys. Run required full suites
  after the candidate is frozen; avoid repeated or unrelated green suites.
- Before a non-trivial batch, state its invariants, scope, why now, stop condition
  and full-suite policy. Bound long runs, save logs and preserve exit status.
  A skipped integration test is not a pass; provide its declared environment.
- For documentation or other low-impact changes, use meaningful structural or
  contract checks. Do not add tests that only repeat the implementation.
- Read [verification workflow](docs/design/engineering-verification-workflow.md)
  before non-trivial tests, performance experiments or environment deployment;
  [test quality](docs/design/test-quality-standard.md) remains normative.
- Investigate review/CI blocks against current code. Fix demonstrated invariant
  violations at their owner and add regression evidence. If a finding relies
  on a stale path or mistaken assumption, show that evidence and correct the
  finding; never bypass a guard or alter behavior merely to obtain a pass.
- Local functional verification uses the L2 `docs/local-independent-deployment.md`
  runbook: `local_l0.py` → `local_app_install.py` → L0 `activate` → `local_l1.py`.
  Local images/tags are accepted; first installation does not prove metadata
  upgrades, rollback or release provenance. Test/Staging may run production
  simulation through their L2 controllers with recorded candidate/topology and
  acceptance evidence. Formal promotion retains its immutable artifact rules.
  Reproduce failures in the smallest supporting environment and close the
  failure class before redispatch; details belong in the verification workflow.
- For performance work, record each run, commits, environment, workload,
  profiles, change, regressions and next hypothesis before the next edit.
  Compare the same workload to both initial and previous baselines. Stop when
  correctness/ownership would break or evidence shows no worthwhile bottleneck.
- Deploy through the target L2 repository's checked-in runbook/workflow, passing
  core, app-pack and overlay refs. Keep secrets, environment flags and tenant
  orchestration there; core must not run or dispatch tenant deployments.
- Use module READMEs and manifests for runnable commands. Finish with
  `git diff --check`. Restore only build-generated `frontend/public/version.json`
  changes unless intentional; preserve pre-existing user edits.

## Further design references

- [Platform architecture](docs/design/nexuscrm-platform-architecture.md) and
  [L0 substrate](docs/design/l0-platform-substrate.md)
- [Flow runtime V2](docs/design/flow-runtime-v2-execution-architecture.md)
- [Public workspace policy](docs/open-source/boundary/public-workspace-layout-and-content-policy.md)
- [Boundary roadmap](docs/refactor/l0-l1-boundary/README.md) and
  [open-source decision index](docs/open-source/decision-index.md)
