service-omni-supervisor-users-create
Create N supervisor users on a Salesforce org for the classic Omni-Channel Supervisor Configuration (
), which binds named user records via
. Users follow a deterministic
supervisor{i}.<suffix>@example.com
pattern so the coordinator can rediscover them across runs. It is the supervisor counterpart to
service-omni-agent-users-create
and shares its detection, password, and idempotency model; the only differences are the username/alias prefixes and the debug-log marker. Binding these users into a config (
service-omni-supervisor-config-deploy
) and granting them supervisor access (
service-omni-supervisor-permset-assign
) are separate leaves.
Inputs
Confirm once, up front:
- (required, no default) — must resolve via .
- Supervisor count (optional, default , range ; the coordinator typically requests 1).
- Profile name (optional, default ). The coordinator overrides this to a Service Cloud profile so supervisors consume Service Cloud licenses; supervisor access itself comes from the standard permission set assigned later.
Usernames and passwords are never accepted from the operator — both are generated (usernames from the org suffix, passwords via Anonymous Apex).
Preconditions and safety
- Target org authenticated via CLI (My Domain URL, not ), Service Cloud license present, CLI ≥ 2.139.6.
- The executing user has and
PermissionsManagePasswordPolicies
(standard on System Administrator).
- Production guardrail: the detect script computes as OR
TrialExpirationDate != null
OR in {Developer Edition, Base Edition}, and the skill blocks with no override when it is false. CDOs, scratch orgs, and dev orgs are permitted.
Password handling (fail-closed). Passwords are set by Anonymous Apex
(
sf user password generate
cannot target Apex-inserted users). The literal appears in the inline executeAnonymous debug log and, only when a debug-log TraceFlag is active for the running user, in a queryable
. The wrapper therefore fails closed
before the first
: it proves via a SOQL-filtered Tooling API query (
) that no active TraceFlag exists. If safety cannot be positively proven, it sets no password at all; the user is left ACTIVE, flagged
password_status:"reset_required"
, and a
explains why. It never deletes logs. A user whose password could not be set is kept ACTIVE and flagged for reset — never deactivated.
Run
bash
# read-only preview (never writes)
bash scripts/detect-and-create.sh plan <org-alias> [count] [profile-name]
# detect, enforce safe_to_write, then insert only the missing supervisors
bash scripts/detect-and-create.sh run <org-alias> [count=1] [profile-name="Standard User"]
is the canonical entry point: it re-runs detection, enforces the production guard, and only then inserts. Do not call
directly — it is internal and does not enforce the guard.
Behavior
Detection. The detector derives an 8-char suffix from
, resolves the profile by name, and queries
for
supervisor{i}.<suffix>@example.com
, splitting occupied slots into active
and
.
Insertion. The Apex loads
assets/create-supervisors.apex.template
, substitutes
/
/
, and inserts only the missing indexes, re-checking inside the transaction to prevent a single run from double-inserting; across
concurrent runs this check is not a guarantee (both can pass their pre-query before either commits), so duplicate protection there relies on the global username-uniqueness constraint plus the
retry (see references/apex-template-notes.md). Created users get the Service Cloud feature (
UserPermissionsSupportUser=true
); if the profile's license does not allow it, the Apex strips the flag and retries (the permset assign will then block until the user is on a suitable license). Each created user is reported via
SUPERVISOR_CREATED|<id>|<username>|<email>
(no password in the marker — it is set by the separate
submission).
Inactive occupants. An inactive user occupying a supervisor slot is not a reusable supervisor and cannot be recreated (usernames are globally unique). It is surfaced as a required manual reactivation and never counted toward the requested slots — counting it would under-provision the config.
Verification. After insertion the detector re-runs and must show
.
Output contract
emits a single JSON object with
∈
|
|
|
|
, plus
,
(
when nothing was created),
,
,
,
users_needing_password_reset
,
, and
.
- — every missing index landed with a working password.
- — some landed but not all, any failed (kept ACTIVE, listed in
users_needing_password_reset
), or a slot is occupied by an inactive user needing reactivation.
- — all requested slots already existed; no DML.
- — plan mode only.
- — precondition failed.
create.created_users[].password
is populated only for users created this run whose
succeeded.
is always empty (this skill never deactivates a user). Generated passwords are a secret: the returned JSON is the only place they appear; a caller that persists stdout must write it only to a restricted
(mode 0600), redact it elsewhere, and delete it after distribution — the coordinator does this automatically.
Limitations
- Username pattern and org suffix are fixed and never operator-configurable — that determinism is what enables idempotent re-runs.
- Creates only supervisor users; it never deletes or deactivates users, including orphaned supervisors from prior runs.
- Common User errors (, , ) are translated into operator-friendly messages rather than surfaced raw.
References
| File | When to read |
|---|
references/apex-patterns.md
| Before running the Apex — Apex structure, User field defaults, password policy, and the profile-localization risk |
references/apex-template-notes.md
| When creation returns a duplicate, license, password, or trace-safety error |
assets/create-supervisors.apex.template
| Loaded by when missing supervisor users must be inserted |
scripts/detect-existing.sh
| Loaded by scripts/detect-and-create.sh
for the read-only org, profile, safety, and existing-user checks |
| Internal writer loaded by scripts/detect-and-create.sh
only after guard checks pass |