service-itsm-agentic-setup-itsm-agentforce-permset-assign

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Assign an ITSM Fulfiller Persona Permission Set (Prompt-Template Access)

分配ITSM Fulfiller角色权限集(提示模板访问权限)

Grants the running user one of the Core-shipped Fulfiller persona permission sets that expose the
svc_itsm_intelligence__*
prompt-template invocable actions on the target org — the actions the Fulfiller NGA agent scripts reference via
source:
/
target: generatePromptResponse://...
. When those invocables are not surfaced by
/services/data/v67.0/actions/custom/generatePromptResponse
for the running user, the Fulfiller agent-configure skill's Phase 6
activate
call returns HTTP 200 with a silent
{success:false, messages:[{... "does not exist"}]}
body and the agent never becomes usable. This skill fixes that gap by assigning the correct Fulfiller persona permset (and its backing license when one exists) — or, when no Fulfiller persona permset is provisioned on the org at all, hands off to the Agentforce Studio configure/validate skill so the ITSM AddOn(s) can be enabled first.
The four Fulfiller persona permsets, their AddOns, PSLs, and the userPerms they grant are documented in
references/permset-topology.md
. All are Core-shipped in namespace
force
— there is no managed-package namespaced permset for this feature.
Employee agent is out of scope. The Employee NGA agent's access model is separate (org-preferences + a different persona layer) and does not map onto these four persona permsets.
Every call runs through the Salesforce CLI (
sf
)
:
  • sf api request rest
    — authenticated Connect API GET (identity, verify read).
  • sf data query
    — SOQL on
    PermissionSet
    (persona presence),
    PermissionSetAssignment
    /
    PermissionSetLicenseAssign
    (idempotency).
  • sf org assign permset
    — assigning the permission set for the running user.
  • No token is ever extracted; no MCP is used.
为目标组织的当前运行用户授予Core内置的Fulfiller角色权限集之一,这些权限集可暴露
svc_itsm_intelligence__*
提示模板可调用动作——Fulfiller NGA agent脚本通过
source:
/
target: generatePromptResponse://...
引用的动作。当这些可调用动作未通过
/services/data/v67.0/actions/custom/generatePromptResponse
为当前运行用户显示时,Fulfiller agent-configure技能的第6阶段
activate
调用会返回HTTP 200,但响应体为静默的
{success:false, messages:[{... "does not exist"}]}
,导致agent始终无法使用。本技能通过分配正确的Fulfiller角色权限集(以及对应的许可证,若存在)来填补这一空白——或者,当组织中未配置任何Fulfiller角色权限集时,转交至Agentforce Studio配置/验证技能,以便先启用ITSM AddOn。
四个Fulfiller角色权限集及其对应的AddOn、PSL和授予的userPerms记录在
references/permset-topology.md
中。所有权限集均为
force
命名空间下的Core内置组件——此功能没有托管包命名空间的权限集。
Employee agent不在范围内。Employee NGA agent的访问模型是独立的(组织偏好设置 + 不同的角色层),与这四个角色权限集不匹配。
所有调用均通过**Salesforce CLI (
sf
)**执行:
  • sf api request rest
    —— 已认证的Connect API GET请求(身份验证、读取验证)。
  • sf data query
    —— 对
    PermissionSet
    (角色存在性)、
    PermissionSetAssignment
    /
    PermissionSetLicenseAssign
    (幂等性)执行SOQL查询。
  • sf org assign permset
    —— 为当前运行用户分配权限集。
  • 从不提取任何令牌;不使用MCP。

Scope

范围

  • In scope: detecting which of the four Fulfiller persona permsets (
    IncidentFulfiller
    ,
    ProblemFulfillerPermSet
    ,
    ChangeRequestFulfillerPermSet
    ,
    ReleaseManagerPermSet
    ) are provisioned on the org, letting the user pick which persona to assign, checking existing assignments, assigning the permission-set license (when the persona is license-gated) and permission set to the running user (or a named user), verifying the target
    svc_itsm_intelligence__*
    invocable actions surface via a follow-up
    /actions/custom/generatePromptResponse
    read.
  • Out of scope: Employee-agent access (different access model, different skill), installing/enabling the ITSM AddOn(s) or content bundle (hand off to
    service-itsm-agentic-setup-agentforce-studio-validate
    ), enabling org-level Agentforce feature toggles, creating a permission set, creating or activating the Fulfiller agent (that's
    service-itsm-agentic-setup-fulfiller-agent-configure
    ), CMDB access (
    service-itsm-agentic-setup-cmdb-access-assign
    ), generic non-ITSM permission-set assignment (
    dx-org-permission-set-assign
    ).
  • 包含范围:检测组织中已配置的四个Fulfiller角色权限集(
    IncidentFulfiller
    ProblemFulfillerPermSet
    ChangeRequestFulfillerPermSet
    ReleaseManagerPermSet
    ),让用户选择要分配的角色,检查现有分配情况,为当前运行用户(或指定用户)分配权限集许可证(当角色受许可证限制时)和权限集,通过后续的
    /actions/custom/generatePromptResponse
    读取验证目标
    svc_itsm_intelligence__*
    可调用动作是否显示。
  • 排除范围:Employee-agent访问(不同的访问模型、不同的技能)、安装/启用ITSM AddOn或内容包(转交至
    service-itsm-agentic-setup-agentforce-studio-validate
    )、启用组织级Agentforce功能开关、创建权限集、创建或激活Fulfiller agent(对应
    service-itsm-agentic-setup-fulfiller-agent-configure
    )、CMDB访问(对应
    service-itsm-agentic-setup-cmdb-access-assign
    )、通用非ITSM权限集分配(对应
    dx-org-permission-set-assign
    )。

Mechanism

机制

Two branches, decided by a read-only detection step first:
  • Branch A — one or more Fulfiller persona permsets exist on the org. Ask the user which persona to assign (do not auto-select — a Fulfiller commonly needs only one). Idempotent assign: PSL first when the persona is license-gated, then permission set, verified by read-back and by a follow-up
    /actions/custom/generatePromptResponse
    read.
  • Branch B — none of the four Fulfiller persona permsets exist on the org. The ITSM AddOn(s) are not provisioned; permset-assign is a no-op. STOP and hand off to
    service-itsm-agentic-setup-agentforce-studio-validate
    so the AddOn(s) can be enabled first.
The two-branch shape is deliberate — the failure signature ("
svc_itsm_intelligence__X
does not exist" on activate) looks identical whether a persona is present-and-unassigned or the AddOn is absent entirely, and there is no way to tell from the activate response alone. The pre-check on the four persona
PermissionSet
names is what disambiguates them.
分为两个分支,首先通过只读检测步骤决定分支:
  • 分支A —— 组织中存在一个或多个Fulfiller角色权限集。询问用户要分配哪个角色(不要自动选择——Fulfiller通常只需要一个角色)。幂等分配:若角色受许可证限制,则先分配PSL,再分配权限集,通过回读和后续的
    /actions/custom/generatePromptResponse
    读取进行验证。
  • 分支B —— 组织中不存在四个Fulfiller角色权限集中的任何一个。ITSM AddOn未配置;权限集分配无意义。停止操作并转交至
    service-itsm-agentic-setup-agentforce-studio-validate
    ,以便先启用AddOn。
这种双分支设计是有意为之——激活时的失败特征(“
svc_itsm_intelligence__X
不存在”)在角色已存在但未分配,以及AddOn完全不存在时看起来完全相同,无法仅通过激活响应区分。通过预先检查四个角色的
PermissionSet
名称才能明确区分这两种情况。

Four helper scripts (all invoked via
Bash
) hold every deterministic decision (A9). Full I/O contracts in
references/helper-contracts.md
; workflow-level usage summarized below:

四个辅助脚本(均通过
Bash
调用)负责所有确定性决策(A9)。完整的I/O契约记录在
references/helper-contracts.md
中;工作流层面的使用总结如下:

  • scripts/classify-permset-availability.mjs
    — Branch A vs B and the per-persona
    needsPsl
    flag. Returns the full
    candidates[]
    (personas actually on the org) for the caller to prompt on.
  • scripts/resolve-target-user.mjs
    — extracts
    005…
    running-user Id from the API-root
    identity
    URL. Fails closed on any malformed shape.
  • scripts/classify-assignment-state.mjs
    — idempotency; pass the sentinel
    NO-PSL
    in place of the PSLA path when the selected persona's
    needsPsl:false
    .
  • scripts/classify-action-surface.mjs
    — Phase 4 verify verdict from the
    /actions/custom/generatePromptResponse
    capture (with optional expected-actions CSV).

  • scripts/classify-permset-availability.mjs
    —— 区分分支A和分支B,以及每个角色的
    needsPsl
    标志。返回完整的
    candidates[]
    (组织中实际存在的角色)供调用方提示用户选择。
  • scripts/resolve-target-user.mjs
    —— 从API根目录的
    identity
    URL中提取
    005…
    格式的当前运行用户ID。若格式有误则终止操作。
  • scripts/classify-assignment-state.mjs
    —— 幂等性检查;当所选角色的
    needsPsl:false
    时,用哨兵值
    NO-PSL
    代替PSLA路径。
  • scripts/classify-action-surface.mjs
    —— 从
    /actions/custom/generatePromptResponse
    的捕获结果中得出第4阶段的验证结论(可附带预期动作CSV)。

Preconditions

前置条件

  1. sf
    CLI installed and authenticated to the target org
    (
    sf org display -o <alias>
    shows Connected). All calls use
    --target-org <alias>
    ; never extract or pass the access token by hand.
  2. API v67.0+.
  3. node
    ≥ 18
    on PATH.
If a precondition fails,
sf
surfaces an auth or
401
/
403
/
404
; report the raw response verbatim and stop.

  1. 已安装
    sf
    CLI并已认证到目标组织
    sf org display -o <alias>
    显示已连接)。所有调用均使用
    --target-org <alias>
    ;切勿手动提取或传递访问令牌。
  2. API版本v67.0+
  3. PATH中存在
    node
    ≥ 18
若前置条件不满足,
sf
会显示认证错误或
401
/
403
/
404
错误;直接报告原始响应并停止操作。

Clarifying questions

澄清问题

Ask only what cannot be inferred from conversation:
  • Target org — the
    sf
    alias. Default to
    sf config get target-org
    if unset.
  • Target user — default to the running user (resolved via
    scripts/resolve-target-user.mjs
    ). If the user asks to assign on behalf of a named user, resolve them by
    Username
    first.
  • Which Fulfiller persona? Incident / Problem / Change / Release. Only ask about personas that are actually provisioned on the org (from
    candidates[]
    ). Do not auto-select — a Fulfiller commonly needs only one persona (e.g. Incident) even when others are provisioned.
  • Confirm the write — assigning a permission-set license consumes a seat and takes effect for a live user session. Present the target user + org + persona permset name, and require an explicit "yes" via
    AskUserQuestion
    before writing.

仅询问无法从对话中推断出的信息:
  • 目标组织 ——
    sf
    别名。若未设置则默认使用
    sf config get target-org
    的结果。
  • 目标用户 —— 默认是当前运行用户(通过
    scripts/resolve-target-user.mjs
    解析)。若用户请求为指定用户分配,则先通过
    Username
    解析该用户。
  • 选择哪个Fulfiller角色? 事件/问题/变更/发布。仅询问组织中已配置的角色(来自
    candidates[]
    )。不要自动选择——即使存在多个角色,Fulfiller通常只需要一个(例如事件处理角色)。
  • 确认写入操作 —— 分配权限集许可证会占用一个席位,并对活跃用户会话生效。显示目标用户 + 组织 + 角色权限集名称,要求用户通过
    AskUserQuestion
    明确回复“是”后再执行写入。

Workflow

工作流

All calls go through
sf
; substitute
<alias>
with the target org.
所有调用均通过
sf
执行;将
<alias>
替换为目标组织。

Phase 1 — Read: which Fulfiller persona permsets are provisioned on this org?

阶段1 —— 读取:此组织中已配置哪些Fulfiller角色权限集?

  1. Query
    PermissionSet
    for the four known Fulfiller persona DeveloperNames:
    bash
    sf data query \
      -q "SELECT Id, Name, Label, LicenseId FROM PermissionSet WHERE Name IN ('IncidentFulfiller','ProblemFulfillerPermSet','ChangeRequestFulfillerPermSet','ReleaseManagerPermSet')" \
      --target-org <alias> --json > /tmp/itsm-personas.json 2>/tmp/itsm-personas.err || true
    (The
    PermissionSet
    namespace on all four is
    force
    — do NOT filter by
    NamespacePrefix
    .)
  2. Classify:
    bash
    node "<skill_dir>/scripts/classify-permset-availability.mjs" /tmp/itsm-personas.json
    The classifier prints
    { personasFound, personasMissing, candidates, verdict, reasons }
    , where each
    candidates[]
    row is
    {Id, Name, Label, LicenseId, needsPsl}
    :
    • verdict:"ASSIGN"
      (≥1 persona present) ⇒ continue to Phase 2. Present the
      personasFound
      list to the user via
      AskUserQuestion
      and get the selected persona; record its
      Id
      ,
      LicenseId
      , and
      needsPsl
      — they drive whether Phase 2b/2d touch the PSL at all.
    • verdict:"HAND-OFF"
      (none of the four personas present) ⇒ Phase 2 is impossible on this org; go to Phase 3 (Branch B hand-off).
    • verdict:"CANNOT-CONFIRM"
      (query failed) ⇒ surface the raw CLI error verbatim; stop.
  1. 查询
    PermissionSet
    获取四个已知Fulfiller角色的DeveloperName:
    bash
    sf data query \
      -q "SELECT Id, Name, Label, LicenseId FROM PermissionSet WHERE Name IN ('IncidentFulfiller','ProblemFulfillerPermSet','ChangeRequestFulfillerPermSet','ReleaseManagerPermSet')" \
      --target-org <alias> --json > /tmp/itsm-personas.json 2>/tmp/itsm-personas.err || true
    (四个权限集的
    PermissionSet
    命名空间均为
    force
    ——请勿按
    NamespacePrefix
    过滤。)
  2. 分类:
    bash
    node "<skill_dir>/scripts/classify-permset-availability.mjs" /tmp/itsm-personas.json
    分类器会输出
    { personasFound, personasMissing, candidates, verdict, reasons }
    ,其中每个
    candidates[]
    条目为
    {Id, Name, Label, LicenseId, needsPsl}
    • verdict:"ASSIGN"
      (存在≥1个角色)⇒ 进入阶段2。通过
      AskUserQuestion
      向用户展示
      personasFound
      列表并获取所选角色;记录其
      Id
      LicenseId
      needsPsl
      ——这些值决定阶段2b/2d是否需要处理PSL。
    • verdict:"HAND-OFF"
      (四个角色均不存在)⇒ 此组织无法执行阶段2;进入阶段3(分支B转交流程)。
    • verdict:"CANNOT-CONFIRM"
      (查询失败)⇒ 直接显示原始CLI错误;停止操作。

Phase 2 — Assign path (Branch A)

阶段2 —— 分配流程(分支A)

2a. Resolve the target user. Read the identity URL, then extract the user Id via the resolver (do NOT parse the URL by hand; do NOT use
USER_ID()
— Apex-only, rejected by REST; do NOT rely on
/chatter/users/me
403
when Chatter is off):
bash
sf api request rest "/services/data/v67.0/" --method GET --target-org <alias> > /tmp/api-root.json 2>/tmp/api-root.err || true
node "<skill_dir>/scripts/resolve-target-user.mjs" /tmp/api-root.json
The resolver prints
{ userId, identity, verdict, reasons }
. On
verdict:"RESOLVED"
use
userId
as the running user; on
verdict:"CANNOT-CONFIRM"
surface the reasons verbatim and stop — do NOT guess.
If the user asks to assign on behalf of a named user instead, resolve by
Username
:
bash
sf data query \
  -q "SELECT Id, Username, Name, IsActive FROM User WHERE Username = '<username>'" \
  --target-org <alias> --json > /tmp/user-lookup.json 2>/tmp/user-lookup.err || true
2b. Idempotency read. Query the
PermissionSetAssignment
for the target user + selected persona's
Id
(SOQL shape in
references/cli-invocation.md
), and then branch on the selected persona's
needsPsl
:
  • needsPsl:true
    — query the
    PermissionSetLicenseAssign
    for the target user + the persona's
    LicenseId
    , then classify:
    bash
    node "<skill_dir>/scripts/classify-assignment-state.mjs" /tmp/psa-existing.json /tmp/psla-existing.json
  • needsPsl:false
    — skip the PSLA query entirely; pass the sentinel:
    bash
    node "<skill_dir>/scripts/classify-assignment-state.mjs" /tmp/psa-existing.json NO-PSL
The classifier prints
{ permsetAssigned, licenseAssigned, needsWrite, verdict, reasons }
. If
needsWrite:false
⇒ Phase 4 (verify only). Else continue to Phase 2c.
2c. Confirm-to-write checkpoint (REQUIRED). Present the target user + org + persona permset name and require an explicit "yes" via
AskUserQuestion
. On "no", stop and report the current state without any writes.
2d. Assign — order depends on the selected persona's
needsPsl
:
  • needsPsl:true
    — POST the PSL to
    /sobjects/PermissionSetLicenseAssign
    FIRST, then run
    sf org assign permset --name <permsetName> --on-behalf-of <userId>
    . Assigning the permission set without the PSL sticks the assignment but the license backing it never activates. Exact call shapes:
    references/cli-invocation.md
    .
  • needsPsl:false
    — SKIP the PSL POST entirely; run
    sf org assign permset
    only. (This is normal for
    ReleaseManagerPermSet
    — its Fulfiller gating is on the org-preference layer, not on a PSL. Assigning the permset is still the correct write.)
Response handling:
  • 201
    on POST /
    success:true
    on
    sf org assign permset
    ⇒ assigned.
  • 400 DUPLICATE_VALUE
    on the PSL POST ⇒ user already had it; treat as success, not error.
  • 400 INSUFFICIENT_ACCESS
    / seat-exhaustion on the PSL POST ⇒ STOP for this write; tell the user the PSL has no seats available.
2a. 解析目标用户。读取身份URL,然后通过解析器提取用户ID(请勿手动解析URL;请勿使用
USER_ID()
——仅适用于Apex,会被REST拒绝;请勿依赖
/chatter/users/me
——当Chatter关闭时会返回
403
):
bash
sf api request rest "/services/data/v67.0/" --method GET --target-org <alias> > /tmp/api-root.json 2>/tmp/api-root.err || true
node "<skill_dir>/scripts/resolve-target-user.mjs" /tmp/api-root.json
解析器会输出
{ userId, identity, verdict, reasons }
。若
verdict:"RESOLVED"
则使用
userId
作为当前运行用户;若
verdict:"CANNOT-CONFIRM"
则直接显示原因并停止操作——请勿猜测。
若用户请求为指定用户分配,则通过
Username
解析:
bash
sf data query \
  -q "SELECT Id, Username, Name, IsActive FROM User WHERE Username = '<username>'" \
  --target-org <alias> --json > /tmp/user-lookup.json 2>/tmp/user-lookup.err || true
2b. 幂等性读取。查询目标用户 + 所选角色
Id
PermissionSetAssignment
(SOQL格式见
references/cli-invocation.md
),然后根据所选角色的
needsPsl
分支处理:
  • needsPsl:true
    —— 查询目标用户 + 角色
    LicenseId
    PermissionSetLicenseAssign
    ,然后分类:
    bash
    node "<skill_dir>/scripts/classify-assignment-state.mjs" /tmp/psa-existing.json /tmp/psla-existing.json
  • needsPsl:false
    —— 完全跳过PSLA查询;传递哨兵值:
    bash
    node "<skill_dir>/scripts/classify-assignment-state.mjs" /tmp/psa-existing.json NO-PSL
分类器会输出
{ permsetAssigned, licenseAssigned, needsWrite, verdict, reasons }
。若
needsWrite:false
⇒ 进入阶段4(仅验证)。否则进入阶段2c。
2c. 写入确认检查点(必填)。显示目标用户 + 组织 + 角色权限集名称,要求用户通过
AskUserQuestion
明确回复“是”。若回复“否”,则停止操作并报告当前状态,不执行任何写入。
2d. 分配 —— 顺序取决于所选角色的
needsPsl
  • needsPsl:true
    —— 先向
    /sobjects/PermissionSetLicenseAssign
    POST PSL,然后执行
    sf org assign permset --name <permsetName> --on-behalf-of <userId>
    。若未分配PSL就分配权限集,分配会生效但许可证不会激活。具体调用格式见
    references/cli-invocation.md
  • needsPsl:false
    —— 完全跳过PSL POST;仅执行
    sf org assign permset
    。(
    ReleaseManagerPermSet
    通常属于这种情况——其Fulfiller限制在组织偏好设置层,而非PSL。分配权限集仍是正确的操作。)
响应处理:
  • POST返回
    201
    /
    sf org assign permset
    返回
    success:true
    ⇒ 分配成功。
  • PSL POST返回
    400 DUPLICATE_VALUE
    ⇒ 用户已拥有该分配;视为成功,而非错误。
  • PSL POST返回
    400 INSUFFICIENT_ACCESS
    / 席位耗尽 ⇒ 停止此写入操作;告知用户PSL无可用席位。

Phase 3 — Hand-off path (Branch B: no Fulfiller persona provisioned)

阶段3 —— 转交流程(分支B:未配置Fulfiller角色)

  1. When Phase 1 returns
    verdict:"HAND-OFF"
    , none of the four Fulfiller persona permsets exist on this org — the ITSM AddOn(s) are not provisioned. Permset-assign is a no-op in this state. Present the discovery via
    AskUserQuestion
    :
    "None of the Fulfiller persona permission sets (Incident, Problem, Change, Release) is provisioned on this org — no permset can grant access to actions that don't exist yet. Run
    service-itsm-agentic-setup-agentforce-studio-validate
    to diagnose which AddOn needs enabling?"
    (options: Yes, run the readiness check / No, stop here).
    • On Yes: delegate to
      service-itsm-agentic-setup-agentforce-studio-validate
      and let it recommend the configure/bundle-deploy skill.
    • On No: stop and report the current state (no persona provisioned, cannot assign) — no writes.
  1. 当阶段1返回
    verdict:"HAND-OFF"
    时,组织中不存在四个Fulfiller角色权限集中的任何一个——ITSM AddOn未配置。此状态下权限集分配无意义。通过
    AskUserQuestion
    告知用户此发现:
    "此组织未配置任何Fulfiller角色权限集(事件、问题、变更、发布)——无法通过权限集授予尚不存在的动作访问权限。是否运行
    service-itsm-agentic-setup-agentforce-studio-validate
    来诊断需要启用哪个AddOn?"
    (选项:是,运行就绪性检查 / 否,在此停止)。
    • 若选择:转交至
      service-itsm-agentic-setup-agentforce-studio-validate
      ,由其推荐配置/包部署技能。
    • 若选择:停止操作并报告当前状态(未配置角色,无法分配)——不执行任何写入。

Phase 4 — Verify

阶段4 —— 验证

  1. Regardless of write vs skip, re-read
    /actions/custom/generatePromptResponse
    and classify via the helper (never by prose grep — A9). CSV shape and both invocation forms live in
    references/helper-contracts.md
    /
    references/cli-invocation.md
    :
    bash
    sf api request rest "/services/data/v67.0/actions/custom/generatePromptResponse" \
      --method GET --target-org <alias> > /tmp/generate-prompt-response.json 2>/tmp/generate-prompt-response.err || true
    node "<skill_dir>/scripts/classify-action-surface.mjs" /tmp/generate-prompt-response.json [expectedActions-csv]
    The helper prints
    { present, missing, totalItsmActionsSeen, verdict, reasons }
    . On
    SURFACED
    proceed to Phase 5; on
    PARTIAL
    /
    MISSING
    after a successful assign, tell the user the write succeeded but the actions are not surfaced — session refresh or wrong persona. Do not falsely report success. On
    CANNOT-CONFIRM
    surface the reasons verbatim.
  1. 无论执行写入还是跳过写入,重新读取
    /actions/custom/generatePromptResponse
    并通过辅助脚本分类(切勿通过文本匹配——A9)。CSV格式和两种调用方式见
    references/helper-contracts.md
    /
    references/cli-invocation.md
    bash
    sf api request rest "/services/data/v67.0/actions/custom/generatePromptResponse" \
      --method GET --target-org <alias> > /tmp/generate-prompt-response.json 2>/tmp/generate-prompt-response.err || true
    node "<skill_dir>/scripts/classify-action-surface.mjs" /tmp/generate-prompt-response.json [expectedActions-csv]
    辅助脚本会输出
    { present, missing, totalItsmActionsSeen, verdict, reasons }
    。若
    verdict:"SURFACED"
    则进入阶段5;若分配成功后返回
    PARTIAL
    /
    MISSING
    ,则告知用户写入成功但动作未显示——可能需要刷新会话或选择其他角色。请勿虚假报告成功。若
    verdict:"CANNOT-CONFIRM"
    则直接显示原因。

Phase 5 — Aggregate verdict

阶段5 —— 汇总结论

  1. Report one of:
    • ASSIGNED — Branch A wrote, verify saw the target actions surface.
    • ALREADY-ASSIGNED — Branch A found
      needsWrite:false
      ; verify saw the target actions surface. (Assignment is already in place; no writes needed.)
    • HAND-OFF — Branch B; no Fulfiller persona is provisioned. Named the follow-up skill.
    • VERIFY-INCONCLUSIVE — write completed but the verify read didn't surface the expected action set. Surface the observed state verbatim; do not report success.
    • FAILED — any Phase 2d write returned an error other than
      DUPLICATE_VALUE
      . Report the raw error.

  1. 报告以下结论之一:
    • ASSIGNED —— 分支A执行了写入,验证显示目标动作已显示。
    • ALREADY-ASSIGNED —— 分支A发现
      needsWrite:false
      ;验证显示目标动作已显示。(分配已存在;无需写入。)
    • HAND-OFF —— 分支B;未配置任何Fulfiller角色。已指明后续技能。
    • VERIFY-INCONCLUSIVE —— 写入完成但验证读取未显示预期动作集。直接显示观察到的状态;请勿报告成功。
    • FAILED —— 阶段2d的任何写入返回
      DUPLICATE_VALUE
      以外的错误。报告原始错误。

Rules / Constraints

规则/约束

ConstraintRationale
Detect Fulfiller persona presence via the four fixed
PermissionSet.Name
values BEFORE any permset write
The failure signature ("action does not exist" on activate) is identical for AddOn-absent and permset-not-assigned; only the pre-check disambiguates them. The four personas are Core-shipped in namespace
force
— a
NamespacePrefix
filter never returns them
Ask the user which persona to assign — never auto-selectA Fulfiller commonly needs only one persona (e.g. Incident). Auto-assigning the first row returned would over-grant
All decisions are made by helper scripts, never by proseAssignment/idempotency logic is deterministic; prose interpretation is not (A9)
Assign the PSL before the permission set — ONLY when the selected persona's
needsPsl:true
The permission set is license-backed; the license seat must be held before the assignment sticks. When the selected persona has no
LicenseId
,
needsPsl:false
and the PSL POST is skipped entirely
Read
needsPsl
from the SELECTED persona's
LicenseId
, per-row — never from a namespace-wide PSL query
Different personas can have different license shapes on the same org; falling back to a namespace-wide PSL would POST a wrong
PermissionSetLicenseAssign
Resolve the running-user Id via
scripts/resolve-target-user.mjs
— never by prose parsing the
identity
URL
The identity URL's segment shape (
005…
, 15 or 18 chars) is a hard rule; the classifier validates and fails closed
Classify the Phase 4 action surface via
scripts/classify-action-surface.mjs
— never by prose grep of the response
Verify is the gate for reporting SUCCESS vs VERIFY-INCONCLUSIVE; the decision must be deterministic
Treat
400 DUPLICATE_VALUE
on PSL POST as success
It means the user already has that assignment — idempotent, not an error
Never create or edit a permission setThis skill only assigns the standard Fulfiller persona permission set(s); authoring perm sets is out of scope
Never install the AddOn / never toggle org-level Agentforce featuresThat is the
service-itsm-agentic-setup-agentforce-studio-validate
/
-configure
scope; this skill hands off, it does not enable
Verify after write via
/actions/custom/generatePromptResponse
— never trust POST return code alone
The assignment can succeed while the target action surface still doesn't include what the Fulfiller template needs (wrong persona, cache)
Confirm-to-write checkpoint before Phase 2dA permset assign consumes a license seat and takes effect for a live user session
Never extract the access tokenUse
sf api request rest
/
sf data query
/
sf org assign permset
— they use the CLI's stored session
Report exact error text from the CLI responseEnables support to diagnose failures

约束理由
在执行任何权限集写入前,通过四个固定的
PermissionSet.Name
值检测Fulfiller角色是否存在
激活时的失败特征(“动作不存在”)在AddOn缺失和权限集未分配时完全相同;只有预先检查才能区分。四个角色均为
force
命名空间下的Core内置组件——按
NamespacePrefix
过滤永远无法获取它们
询问用户要分配哪个角色——切勿自动选择Fulfiller通常只需要一个角色(例如事件处理角色)。自动选择返回的第一个条目会过度授予权限
所有决策均由辅助脚本做出,切勿通过文本判断分配/幂等性逻辑是确定性的;文本解释具有不确定性(A9)
仅当所选角色的
needsPsl:true
时,先分配PSL再分配权限集
权限集由许可证支持;必须先占用许可证席位,分配才能生效。当所选角色无
LicenseId
时,
needsPsl:false
,完全跳过PSL POST
从所选角色的
LicenseId
逐行读取
needsPsl
——切勿从命名空间级PSL查询获取
同一组织中不同角色的许可证格式可能不同;依赖命名空间级PSL会POST错误的
PermissionSetLicenseAssign
通过
scripts/resolve-target-user.mjs
解析当前运行用户ID——切勿手动解析
identity
URL
identity
URL的段格式(
005…
,15或18位字符)是硬性规则;分类器会验证并在格式错误时终止操作
通过
scripts/classify-action-surface.mjs
分类阶段4的动作显示情况——切勿通过文本匹配响应
验证是报告SUCCESS vs VERIFY-INCONCLUSIVE的关键;决策必须是确定性的
将PSL POST返回的
400 DUPLICATE_VALUE
视为成功
这意味着用户已拥有该分配——具有幂等性,并非错误
切勿创建或编辑权限集本技能仅分配标准Fulfiller角色权限集;权限集创作不在范围内
切勿安装AddOn / 切勿切换组织级Agentforce功能这是
service-itsm-agentic-setup-agentforce-studio-validate
/
-configure
的范围;本技能仅转交,不执行启用操作
写入后通过
/actions/custom/generatePromptResponse
验证——切勿仅信任POST返回码
分配可能成功,但目标动作显示仍可能不包含Fulfiller模板所需的内容(角色错误、缓存)
阶段2c前设置写入确认检查点权限集分配会占用许可证席位,并对活跃用户会话生效
切勿提取访问令牌使用
sf api request rest
/
sf data query
/
sf org assign permset
——它们使用CLI存储的会话
报告CLI响应中的准确错误文本便于支持人员诊断故障

Verification Checklist

验证清单

  • Persona availability classified by
    scripts/classify-permset-availability.mjs
    against the four fixed persona Names — never by prose scanning the query output.
  • User was asked to pick a persona from
    personasFound[]
    — no auto-selection.
  • Target user Id resolved by
    scripts/resolve-target-user.mjs
    — never by prose splitting the identity URL.
  • The SELECTED persona's
    needsPsl
    drove Phase 2b/2d: PSL SOQL + POST were performed when
    true
    and skipped when
    false
    .
  • permsetLicenseId
    used for the PSL POST came from the SELECTED persona's own
    LicenseId
    — never a fallback from a namespace-wide query.
  • On Branch A: existing assignments read via
    sf data query
    before any write, classified by
    scripts/classify-assignment-state.mjs
    (with
    NO-PSL
    sentinel when
    needsPsl:false
    ).
  • On Branch A: user confirmed the write at the Phase 2c checkpoint.
  • On Branch A +
    needsPsl:true
    : PSL was POSTed before the permission set was assigned.
  • DUPLICATE_VALUE
    on the PSL POST was treated as success, not failure.
  • On Branch B: no write was attempted; the hand-off to
    service-itsm-agentic-setup-agentforce-studio-validate
    was offered.
  • Phase 4 verify classified via
    scripts/classify-action-surface.mjs
    — no false ASSIGNED without the helper returning
    verdict:"SURFACED"
    .
  • Aggregate verdict reported (ASSIGNED / ALREADY-ASSIGNED / HAND-OFF / VERIFY-INCONCLUSIVE / FAILED).

  • 通过
    scripts/classify-permset-availability.mjs
    针对四个固定角色名称分类角色可用性——切勿通过文本扫描查询结果。
  • 已让用户从
    personasFound[]
    中选择角色——无自动选择。
  • 通过
    scripts/resolve-target-user.mjs
    解析目标用户ID——切勿手动拆分
    identity
    URL。
  • 所选角色的
    needsPsl
    驱动阶段2b/2d:当
    true
    时执行PSL SOQL + POST,当
    false
    时跳过。
  • PSL POST使用的
    permsetLicenseId
    来自所选角色自身的
    LicenseId
    ——切勿从命名空间级查询获取备用值。
  • 分支A:执行任何写入前通过
    sf data query
    读取现有分配,通过
    scripts/classify-assignment-state.mjs
    分类(当
    needsPsl:false
    时使用
    NO-PSL
    哨兵值)。
  • 分支A:用户已在阶段2c检查点确认写入操作。
  • 分支A +
    needsPsl:true
    :先POST PSL,再分配权限集。
  • PSL POST返回的
    DUPLICATE_VALUE
    已视为成功,而非失败。
  • 分支B:未尝试写入;已提供转交至
    service-itsm-agentic-setup-agentforce-studio-validate
    的选项。
  • 阶段4验证通过
    scripts/classify-action-surface.mjs
    分类——仅当辅助脚本返回
    verdict:"SURFACED"
    时才报告ASSIGNED。
  • 已报告汇总结论(ASSIGNED / ALREADY-ASSIGNED / HAND-OFF / VERIFY-INCONCLUSIVE / FAILED)。

Output Format

输出格式

text
ITSM Fulfiller Persona Permset Assignment (via service-itsm-agentic-setup-itsm-agentforce-permset-assign)

Org:            <org-alias> (API v67.0)
Target user:    <username> (<userId>)
Persona:        <Incident | Problem | Change | Release>
PermSet:        <DeveloperName>

  Personas provisioned on org ...... <comma-separated list | none>
  Existing PSL assignment .......... <yes | no | n/a>
  Existing permset assignment ...... <yes | no>
  Write PSL ........................ <succeeded | already-had | skipped | FAILED>
  Write permset .................... <succeeded | already-had | skipped | FAILED>
  Verify actions surface ........... <yes | partial | no>

Verdict: ASSIGNED | ALREADY-ASSIGNED | HAND-OFF | VERIFY-INCONCLUSIVE | FAILED
Reason:  <plain-language explanation, or empty on success>

Next steps:
  - <If ASSIGNED / ALREADY-ASSIGNED: "Re-run service-itsm-agentic-setup-fulfiller-agent-configure — the invocable actions should now surface, and the activate call will succeed.">
  - <If HAND-OFF: "No Fulfiller persona is provisioned on this org. Run service-itsm-agentic-setup-agentforce-studio-validate to identify which AddOn needs enabling.">
  - <If VERIFY-INCONCLUSIVE: list the observed state verbatim; a session refresh or a different persona may be required>
  - <If FAILED: list the observed error verbatim + remediation>
Keep internal jargon (record Ids, HTTP status codes,
FUNCTIONALITY_NOT_ENABLED
,
DUPLICATE_VALUE
, object/developer names,
sf api request rest
) out of user-facing output.

text
ITSM Fulfiller角色权限集分配(通过service-itsm-agentic-setup-itsm-agentforce-permset-assign)

组织:            <org-alias> (API v67.0)
目标用户:    <username> (<userId>)
角色:        <事件 | 问题 | 变更 | 发布>
权限集:        <DeveloperName>

  组织中已配置的角色 ...... <逗号分隔列表 | 无>
  现有PSL分配 .......... <是 | 否 | 不适用>
  现有权限集分配 ...... <是 | 否>
  PSL写入 ........................ <成功 | 已存在 | 跳过 | 失败>
  权限集写入 .................... <成功 | 已存在 | 跳过 | 失败>
  验证动作显示 ........... <是 | 部分显示 | 否>

结论: ASSIGNED | ALREADY-ASSIGNED | HAND-OFF | VERIFY-INCONCLUSIVE | FAILED
原因:  <通俗易懂的解释,成功时留空>

下一步:
  - <若为ASSIGNED / ALREADY-ASSIGNED: "重新运行service-itsm-agentic-setup-fulfiller-agent-configure——可调用动作现在应已显示,激活调用将成功。">
  - <若为HAND-OFF: "此组织未配置任何Fulfiller角色。运行service-itsm-agentic-setup-agentforce-studio-validate以确定需要启用哪个AddOn。">
  - <若为VERIFY-INCONCLUSIVE: 直接显示观察到的状态;可能需要刷新会话或选择其他角色>
  - <若为FAILED: 直接显示观察到的错误 + 补救措施>
用户输出中请勿包含内部术语(记录ID、HTTP状态码、
FUNCTIONALITY_NOT_ENABLED
DUPLICATE_VALUE
、对象/开发者名称、
sf api request rest
)。

Reference File Index

参考文件索引

FileWhen to read
references/permset-topology.md
Any change to the persona list — the four Core-shipped Fulfiller permsets, their AddOns/PSLs/userPerms, and the fixed-lookup discovery query
references/cli-invocation.md
Every phase — exact
sf api request rest
/
sf data query
/
sf org assign permset
call shapes, the never-extract-token rule, response envelopes
references/helper-contracts.md
The input/output shapes of all four helper scripts (
classify-permset-availability.mjs
,
resolve-target-user.mjs
,
classify-assignment-state.mjs
,
classify-action-surface.mjs
) and how to interpret each verdict
文件阅读时机
references/permset-topology.md
角色列表有任何变更时——四个Core内置Fulfiller权限集、其AddOn/PSL/userPerms,以及固定查询发现逻辑
references/cli-invocation.md
每个阶段——
sf api request rest
/
sf data query
/
sf org assign permset
的具体调用格式、永不提取令牌规则、响应包结构
references/helper-contracts.md
所有四个辅助脚本(
classify-permset-availability.mjs
resolve-target-user.mjs
classify-assignment-state.mjs
classify-action-surface.mjs
)的输入/输出格式,以及如何解读每个结论