Configure the tenant, wire integration, manage rights — principle vs policy, tenant beats pack, never auto-delete.
You configure the tenant without touching engine code. The line you must hold is principle versus policy (/app/config). A PRINCIPLE is fixed and settable nowhere — it is the product's constitution, and the UI renders it locked. A POLICY is configurable, and every policy resolves through a strict precedence: registry default, then the industry pack, then the tenant. The trust guarantee is that TENANT ALWAYS BEATS PACK — improving a pack ships better defaults but never overwrites a business choice you have made. A source badge on every control shows whether the live value is Default, Pack, or Tenant.
A tenant boots on its industry pack. There are nine (pharma, FMCG, FMEG, semicon, telecom, discrete, metal-cable, textile, and a generic fallback), each supplying policies, lexicon, planning hierarchy, service classes and first-class attributes as versioned, best-practice defaults. A provisioned tenant comes up demo-ready on its pack; where the pack's opinion is wrong for the customer, you override at the tenant scope and your override wins — permanently and audibly.
Users, groups and rights are yours (/app/groups). Three base roles compose the visibility baseline — viewer (read plus Assist), planner (run engines, approve, override), admin (users, configuration, org settings) — and groups layer a reusable rights set on top; there is no custom-role engine. Module rights are DENY rows: withhold a module and its nav link hides and its API refuses, while admins stay immune. Data-scope grants are additive on top of the role baseline.
Integration is per-object and honest (/app/integration). Every object carries its own transport — file or SAP RFC — and both share the exact same map-and-load path; only mapped fields are stored and dropped columns are reported by name ("no data without a contract"). Write-back mode is immediate, task-trigger, or the default never: on never the outbound is refused before transport with the read-first reason; task-trigger queues an idempotent outbound document and the nightly run flushes it after the plan. Snapshot loads (open POs, returns) replace per key — a re-load never double-counts.
Lifecycle and audit close the loop. lifecycle.staleAfterMonths (default twelve) quarantines masters that have gone quiet, but the standing rule is NEVER auto-delete — aged data is set aside for a human, not destroyed. And every mutation anywhere in the product is audit-logged with the actor, the action, and an old→new detail (Settings → Audit), because in an enterprise posture the audit trail is not a feature, it is the floor.