platform-dsar-policy-manage

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

platform-dsar-policy-manage: DsarPolicy Right to Portability, end to end

platform-dsar-policy-manage:DsarPolicy数据可携权全流程管理

Operate a
DsarPolicy
— the metadata driving a Right-to-Portability (RTP) export — across its lifecycle: configure the tree, run an export, audit runs. A
DsarPolicy
is a read/export map: it names which of a subject's records an export collects. It never deletes anything. The value here is judgment, not XML plumbing.
FIRST LINE OF EVERY RESPONSE — do not narrate the skill. Your first output token is work or the answer, never a play-by-play. Do not open with "This is a coverage-gap audit / Workflow D…", "Let me read the skill's guide/mechanics…", "Per rule #1…", or "Let me discover the SOR…". Don't name the workflow, announce which reference files you're about to read, or describe your method before doing it — just start doing it (call the tool) and, when done, present the result. This is load-bearing call #8, stated up front because it governs your very first token. A plain-language sentence about the user's data/org is fine; a sentence about the skill, its workflows, rules, tools, or files is not.
对驱动数据可携权(RTP)导出的元数据——
DsarPolicy
——进行全生命周期操作:配置映射树、运行导出任务、审计运行记录。
DsarPolicy
是一种读取/导出映射:它指定导出将收集主体的哪些记录。它绝不会删除任何内容。本技能的核心价值在于决策判断,而非XML配置操作。
每段回复的第一行规则——不要叙述技能本身。 输出的第一个内容必须是工作内容或答案,绝不能是操作说明。请勿以“这是覆盖缺口审计/工作流D…”、“让我阅读技能指南/机制…”、“根据规则#1…”或“让我发现SOR…”开头。不要命名工作流、宣布即将读取的参考文件,或在执行前描述方法——直接开始执行(调用工具),完成后呈现结果。这是优先级最高的规则#8,提前说明是因为它决定了你的首个输出内容。可以用平实语言描述用户的数据/组织;但禁止描述技能、工作流、规则、工具或文件

Load-bearing calls (get these right or the task fails)

核心操作规则(必须严格遵守,否则任务失败)

These override any leading phrasing in the request. Read them first, every time. Call #1 is the literal first action of every task — before you pick a workflow, before any
sf
command.
  1. Route through the SOR tool FIRST — before any
    sf
    /endpoint call, no exceptions.
    The very first action of every task here — including a trivial read-only "does a policy exist / list the policies" lookup — is to scan this run's available tools for a capability-routing tool exposing discover / describe / dispatch verbs (project-codey / Headless 360 today; any host prefix such as
    mcp__<host>__discover
    ; match the verb shape, not a fixed name). If one is present, that is the entry move:
    discover → describe → dispatch
    the
    DsarPolicyManager
    SOR (owner Privacy Center;
    isActive
    gates execute/edit/delete) and reject look-alikes (data mask, generic consent, subject erasure). Do not reach for
    sf
    first — grabbing
    sf
    on reflex because the task "looks like a quick lookup" is the top recurring miss, and it is wrong even when it would work.
    sf
    is the fallback only when no routing tool is in reach (checking
    sf org list
    to see which orgs are authenticated locally is fine — that is a client-side auth check, not a SOR call). Every
    sf
    /
    salesforce-api-context
    command shown in the workflows below is the no-routing-tool spelling; when the routing tool is present, dispatch the equivalent operation through it instead. Detail:
    references/headless-sor.md
    .
  2. Export, never erasure. A run produces an export file; it does not erase/redact/delete the subject. If the request frames it as deletion ("remove them", "erase", "clear out"), correct that first and never report the subject as erased. Erasure is a separate mechanism — if that's the goal, say so and stop. You may still export if authorization is clear, after correcting the premise.
  3. Do not guess personal data. Which objects/relationships hold the subject's data is the admin's classification call. If the request delegates it ("figure out what counts", "wire the whole thing up"), do not author a guessed tree — enumerate the decisions the admin must make (roots; per-relationship follow/stop; fields), mark any proposal pending admin disposition. An over-broad guess exports other people's records.
  4. Caps are hard — name the cap and stop; don't graph-walk. Tree caps: 10 children/path, depth 10, 200 nodes. An unbounded request ("everything", "the whole graph") cannot fit. Do not enumerate the object graph to "try" (never finishes, burns the turn). Name the specific cap exceeded and offer a bounded alternative (split policies, prune branches). Never silently truncate.
  5. Poll a couple of times, then ask — don't block on terminal. The run handle serves status and file. An early getfile returns
    NOT_FOUND
    /
    "This file isn't ready yet"
    — the contract working, not a failure. Poll ≈2–3×; if still not terminal, stop and ask the user whether to keep polling — don't loop. A run can sit non-terminal indefinitely on downstream async processing — platform / Tool Factory territory, not this skill's to diagnose or reach into; report status in plain terms (running / completed / errored) and let the user decide. Never download before terminal. A failed run can return HTTP 201 — read the envelope /
    RequestStatus
    in the body, not the HTTP code. getfile segment is
    dsr
    , not
    dsar
    .
  6. History is a read. Run history = a SOQL query over
    DsarPolicyLog
    . Not
    installListView
    , not a UI list; it starts no run.
  7. Never auto-activate or republish. Activation is a deliberate, human-confirmed step. Editing an ACTIVE policy needs it deactivated first — deactivate → edit → stop, report, get explicit user confirmation before reactivating. New policies stay INACTIVE until the user activates. Auto-republishing breaks the reviewable audit trail disputes depend on.
  8. Work silently — never narrate the skill's internals (applies to every workflow; see the masthead above). The user asked a domain question; answer it, don't describe how the skill answers it. Run the tools and present the result — no intermediate narration of: that you are about to read / are reading the skill's guide, mechanics, or reference files ("let me read the skill's guide and mechanics"); which workflow this is ("this is a coverage-gap audit / Workflow D", "Workflow C-style read") — the user does not think in workflow letters, so never name one; which SOR/routing tool you're using or that you're "loading schemas / discovering / dispatching"; the load-bearing rule numbers ("per rule #1"); the reject-look-alikes step; the operation graph or GET-vs-dispatch plumbing (
    getAccessInfo
    ,
    dispatch_readonly
    , etc.). These steer how you work — they are not status updates. (The harness still shows its own plain tool-call lines; that is fine — just don't add your own play-by-play.) What the user DOES see: the final answer, and — where a call requires it — a plain-language question (
    AskUserQuestion
    ) or a short scope/consent line about their org ("I only listed policies; I changed nothing", "this exports, it doesn't delete"). Rule of thumb: a sentence about their data/org can be user-facing; a sentence about the skill, its workflows, steps, tools, rules, or files stays internal. Workflow D's method preamble is the one allowed "here's how I'll do it" line, and even it must be plain-language about the audit approach ("I'll look one level out from your policy's objects and flag fields that might hold personal data") — it names no workflow letter, rule, tool, or file. That preamble is not a licence to say "this is Workflow D" or "let me read the mechanics".
这些规则优先级高于请求中的任何引导性表述。每次任务都要先阅读这些规则。规则#1是所有任务的首个操作——在选择工作流、执行任何
sf
命令之前必须完成。
  1. 首先通过SOR工具路由——在任何
    sf
    /端点调用之前,无例外。
    所有任务的首个操作——包括简单的只读查询“策略是否存在/列出策略”——都是扫描本次运行的可用工具,寻找暴露discover / describe / dispatch动词的能力路由工具(当前为project-codey / Headless 360;任何前缀如
    mcp__<host>__discover
    匹配动词形态,而非固定名称)。如果存在该工具,必须以此作为入口步骤:
    discover → describe → dispatch
    DsarPolicyManager
    SOR(归属Privacy Center;
    isActive
    控制执行/编辑/删除权限),并拒绝类似工具(数据掩码、通用同意、主体擦除工具)。请勿直接使用
    sf
    ——因任务“看起来像快速查询”就本能调用
    sf
    是最常见的错误,即使偶然可行也是违规的。
    sf
    仅作为无路由工具可用时的 fallback(检查
    sf org list
    查看本地已认证的组织是允许的——这是客户端权限检查,而非SOR调用)。以下工作流中展示的所有
    sf
    /
    salesforce-api-context
    命令均为无路由工具时的写法;当路由工具存在时,需通过该工具调度等效操作。详细说明:
    references/headless-sor.md
  2. 仅导出,绝不擦除。 运行结果为导出文件;不会擦除/编辑/删除主体数据。如果请求将其描述为删除(“移除”、“擦除”、“清理”),首先纠正该表述,绝不能报告主体数据已被擦除。擦除是独立机制——如果用户目标是擦除,请说明并停止操作。在纠正前提后,若授权明确仍可执行导出。
  3. 请勿猜测个人数据。 哪些对象/关系包含主体的数据是管理员的分类决策。如果请求将该决策委托给你(“找出哪些数据符合要求”、“完成整个配置”),请勿编写猜测的映射树——列出管理员必须做出的决策(根对象;每个关系是否继续遍历;字段),并标记任何提议为待管理员处置。过于宽泛的猜测会导出他人的记录。
  4. 严格遵守上限——明确说明上限并停止;请勿遍历整个图谱。 映射树上限:每个路径最多10个子节点,深度最多10层,总节点数最多200个。无边界请求(“所有数据”、“整个图谱”)无法满足上限。请勿遍历图谱尝试实现(永远无法完成,浪费资源)。明确说明超出的具体上限,并提供有边界的替代方案(拆分策略、修剪分支)。绝不能静默截断。
  5. 轮询几次后询问——不要一直等待任务完成。 运行句柄用于查询状态获取文件。早期调用
    getfile
    会返回
    NOT_FOUND
    /
    "This file isn't ready yet"
    ——这是正常的合约行为,而非失败。轮询≈2–3次;如果仍未完成,停止并询问用户是否继续轮询——不要循环执行。任务可能因下游异步处理长期处于未完成状态——这属于平台/Tool Factory范畴,非本技能可诊断或干预;用平实语言报告状态(运行中/已完成/出错),由用户决定后续操作。绝不能在任务完成前下载文件。失败的运行可能返回HTTP 201——请读取响应体中的信封/
    RequestStatus
    ,而非HTTP状态码。getfile的路径段为**
    dsr
    **,而非
    dsar
  6. 历史记录是只读操作。 运行历史 = 对
    DsarPolicyLog
    执行SOQL查询。请勿使用
    installListView
    或UI列表;此操作不会启动任何运行。
  7. 绝不自动激活或重新发布。 激活是需人工确认的 deliberate操作。编辑ACTIVE状态的策略需先将其停用——停用 → 编辑 → 停止,报告并获取用户明确确认后再重新激活。新策略默认保持INACTIVE状态,直到用户手动激活。自动重新发布会破坏争议所需的可审计追踪记录。
  8. 静默工作——绝不叙述技能内部逻辑(适用于所有工作流;见顶部规则)。 用户询问的是业务问题;请直接回答,不要描述技能如何回答问题。运行工具并呈现结果——禁止中间叙述:即将读取/正在读取技能指南、机制或参考文件(“让我阅读技能指南和机制”);当前使用的工作流(“这是覆盖缺口审计/工作流D”、“工作流C式读取”)——用户不会以工作流代号思考,因此绝不能提及;正在使用的SOR/路由工具,或“加载 schema / 发现 / 调度”的操作;核心规则编号(“根据规则#1”);拒绝类似工具的步骤;操作图谱或GET-vs-dispatch机制(
    getAccessInfo
    dispatch_readonly
    等)。这些内容指导你如何工作——而非状态更新。(工具本身会显示简单的调用日志;这是允许的——只需不要添加自己的操作说明。)用户可见内容:最终答案,以及——当调用需要时——平实语言的问题(
    AskUserQuestion
    )或关于用户组织的简短范围/同意说明(“我仅列出了策略;未进行任何修改”、“此操作是导出,而非删除”)。经验法则:关于
    用户数据/组织
    的句子可面向用户;关于技能、工作流、步骤、工具、规则或文件的句子需保留在内部。工作流D的方法前言是唯一允许的“我将如何操作”表述,且必须用平实语言描述审计方法(“我将从你的策略对象向外查看一层,标记可能包含个人数据的字段,并给出各自的理由”)——禁止提及工作流代号、规则、工具或文件。该前言并非允许你说“这是工作流D”或“让我阅读机制”。

The DsarPolicy object model

DsarPolicy对象模型

Each entity is reached a different way — guessing the surface is the top time-sink.
EntityWhat it isHow you reach it
DsarPolicy
Policy shell + lifecycle (ACTIVE/INACTIVE)Metadata API
DsarPolicyPath
A tree node: a root object, or a parent→related relationshipMetadata API (child of
DsarPolicy
)
DsarPolicyField
A field collected at a pathMetadata API (child of a path)
DsarPolicyLog
Run log (one row per run)Standard SOQL
Execute an exportConnect DSR endpoint (
POST
)
Status / getfileConnect DSR endpoint on the handle; getfile segment
dsr
Resolve the exact Connect route/version at run time via
salesforce-api-context
(or
sf
). Don't
sf sobject describe DsarPolicy*
— the tree is metadata; only
DsarPolicyLog
answers standard SOQL. On an MCP surface, each row is one
DsarPolicyManager
operation.
每个实体的访问方式不同——猜测访问方式是最耗时的错误。
实体说明访问方式
DsarPolicy
策略框架 + 生命周期(ACTIVE/INACTIVE)Metadata API
DsarPolicyPath
树节点:根对象,或父→关联关系Metadata API
DsarPolicy
的子对象)
DsarPolicyField
路径下收集的字段Metadata API(路径的子对象)
DsarPolicyLog
运行日志(每次运行对应一行)标准SOQL
执行导出Connect DSR端点
POST
查询状态 / 获取文件通过句柄调用Connect DSR端点;getfile路径段为
dsr
运行时通过
salesforce-api-context
(或
sf
)确定准确的Connect路由/版本。请勿执行
sf sobject describe DsarPolicy*
——映射树是元数据;仅
DsarPolicyLog
支持标准SOQL查询。在MCP界面中,每行对应一个
DsarPolicyManager
操作。

Pick the workflow (by the verb)

根据动词选择工作流

Want to…RunEnds when
Set up / edit a policy treeA — ConfigureBounded policy authored INACTIVE; or an unbounded request's cap is named / an under-specified one's decisions enumerated — and stops
Run an export for a subjectB — ExportSubject resolved to a root Id, run status read (running/completed/errored), file located on success — or, if still running after a couple polls, the user is asked whether to continue
See past runsC — HistoryPrior runs reported from
DsarPolicyLog
, no run started
Find PII not yet coveredD — Coverage gapCandidates surfaced with per-field reasons, disposition left to the admin — read-only
Mixed request → do the one asked; don't add an export to a configure, or a run to a history.
Every workflow below assumes call #1 is already done — you have routed through the discover/ describe/dispatch SOR tool (or confirmed none is in reach). The
sf
/
salesforce-api-context
commands in each workflow are the no-routing-tool spelling; with the routing tool present, dispatch the equivalent operation through it.
想要…运行工作流结束条件
设置 / 编辑策略树A — 配置生成有边界的INACTIVE状态策略;或明确无边界请求的上限/列出未明确请求的决策项——然后停止
为主体运行导出B — 导出主体解析为根ID,获取运行状态(运行中/已完成/出错),成功时定位到文件——或,若轮询几次后仍未完成,询问用户是否继续
查看历史运行记录C — 历史
DsarPolicyLog
返回历史运行记录,不启动任何运行
查找未覆盖的PIID — 覆盖缺口分析列出候选字段及各自理由,处置权交由管理员——只读操作
混合请求 → 仅执行用户明确要求的操作;不要在配置时添加导出,或在查询历史时启动运行。
以下所有工作流均假设已完成规则#1——已通过discover/describe/dispatch路由工具完成路由(或确认无路由工具可用)。各工作流中的
sf
/
salesforce-api-context
命令均为无路由工具时的写法;当路由工具存在时,需通过该工具调度等效操作。

Workflow A — Configure

工作流A — 配置

Recipe (metadata shape, relationship/field resolution, lifecycle transitions):
references/configure.md
.
  1. Classify first — short-circuit before any describe. Three shapes; two never reach authoring:
    • Unbounded ("everything", "whole graph") — can't fit caps. Don't describe/walk. Write the cap-refusal report (call #3), stop.
    • Under-specified — delegates classification, no root/field named. Don't author a guess. Write the elicitation report (the admin's decisions; support multiple roots; proposals pending disposition), stop.
    • Bounded & specified — named roots/relationships/fields fitting the caps → continue.
  2. Confirm type + describe named objects only (don't assume names, don't expand beyond what's named):
    bash
    sf org list metadata --metadata-type DsarPolicy --target-org <alias> --json
    sf sobject describe --sobject <NamedObject> --target-org <alias> --json
    If
    DsarPolicy
    can't be listed/described, surface it and stop (accepted terminal outcome).
  3. Validate the tree (don't eyeball caps/names):
    bash
    python3 scripts/validate-policy-tree.py <tree.json>
    Checks children≤10, depth≤10, nodes≤200, and devname
    [a-zA-Z]+[a-zA-Z0-9_]*
    .
  4. Author metadata INACTIVE under
    ${outputDir}
    , faithful to the sanctioned strategy — add no unapproved path, drop none approved.
    Lifecycle gate: INACTIVE to edit/delete, ACTIVE to execute. Change an ACTIVE policy by deactivate → edit → STOP; get explicit user confirmation before reactivating (call #7).
  5. Deploy (best effort):
    sf project deploy start --source-dir <outputDir> --target-org <alias> --json
    . Deploy may fail where the type isn't fully enabled — surface the raw error + prerequisite; don't fake success. The classification work is valid regardless.
  6. Report the outcome reached — cap-refusal / elicitation / authored — per
    references/report-format.md
    . Never a truncated tree called "complete".
参考文档(元数据格式、关系/字段解析、生命周期转换):
references/configure.md
  1. 首先分类——在任何描述操作前终止不符合条件的请求。 三种请求形态;其中两种无需进入编写阶段:
    • 无边界(“所有数据”、“整个图谱”)——超出上限。请勿描述/遍历图谱。编写上限拒绝报告(规则#3),停止操作。
    • 未明确指定——将分类决策委托给你,未指定根对象/字段。请勿编写猜测的映射树。编写决策引导报告(列出管理员需做出的决策;支持多个根对象;提议标记为待处置),停止操作。
    • 有边界且明确指定——指定的根对象/关系/字段符合上限要求 → 继续操作。
  2. 确认类型 + 仅描述指定对象(不要假设名称,不要超出指定范围扩展):
    bash
    sf org list metadata --metadata-type DsarPolicy --target-org <alias> --json
    sf sobject describe --sobject <NamedObject> --target-org <alias> --json
    如果无法列出/描述
    DsarPolicy
    ,请告知用户并停止操作(这是可接受的终止结果)。
  3. 验证映射树(不要手动检查上限/名称):
    bash
    python3 scripts/validate-policy-tree.py <tree.json>
    检查子节点数≤10、深度≤10、总节点数≤200,以及开发名称符合
    [a-zA-Z]+[a-zA-Z0-9_]*
    格式。
  4. ${outputDir}
    下编写INACTIVE状态的元数据
    ,严格遵循批准的策略——不要添加未批准的路径,不要遗漏已批准的内容。
    生命周期限制: INACTIVE状态可编辑/删除,ACTIVE状态可执行。修改ACTIVE状态的策略需遵循停用 → 编辑 → 停止流程;重新激活前需获取用户明确确认(规则#7)。
  5. 部署(尽力而为):
    sf project deploy start --source-dir <outputDir> --target-org <alias> --json
    。 如果类型未完全启用,部署可能失败——请展示原始错误及前置条件;不要伪造成功。分类工作本身是有效的。
  6. 报告最终结果——上限拒绝 / 决策引导 / 已编写——参考
    references/report-format.md
    。绝不能将截断的映射树称为“完整”。

Workflow B — Run an export

工作流B — 运行导出

Endpoints, sample envelopes, poll/download sequence:
references/export-and-history.md
.
  • B0. Resolve the subject. Requests arrive as email / name / id, not a
    dataSubjectId
    . Resolve to the Id of a record whose type is a ROOT of the chosen policy (Account / Contact / Individual / Lead / User) — e.g. SOQL
    Lead
    /
    Contact
    by
    Email
    . Confirm the type is a policy root (execute matches only the root subtree of the subject's type — a non-root subject exports nothing). On 0 / many / non-root matches, stop and report; never execute a guessed Id.
  • B1. Preconditions. Policy must be ACTIVE (else route to A). Resolve DSR routes via
    salesforce-api-context
    .
    • Pick the policy deliberately: named → use it; else the in-context policy; if none is established or multiple ACTIVE could match, ask to confirm (e.g. "Run
      <policy>
      for
      <subject>
      — confirm?"
      ). Never pick silently.
    • Access: on
      401
      /
      403
      , name the guard and stop — user perm
      Consent.CAN_EXECUTE_DSAR_POLICY
      , org feature
      Consent.hasDsarPortability
      . State the poll-then-download ordering even on this error path (accepted terminal outcome; don't retry blindly).
  • B2. Consent gate + correct deletion framing (call #2). If framed as deletion, correct it first (export, not erasure). If authorization is ambiguous, ask via
    AskUserQuestion
    ; clear authorization → proceed.
  • B3. Execute — trust the envelope, not the HTTP code. POST execute, capture the run handle. A failed run can return HTTP 201 — read the envelope status; report failure if it says so.
  • B4. Poll ≈2–3×, then ask; download only after terminal (call #5). Poll the handle (or
    DsarPolicyLog.RequestStatus
    ). Early
    NOT_FOUND
    / "not ready" is expected. Still not terminal after a couple polls → stop and ask whether to keep polling; don't loop (non-terminal = downstream async, not this skill's to diagnose). Report running / completed / errored.
  • B5. Download (terminal-success only) — segment
    dsr
    .
    A
    dsar
    segment 404s. Report where the export landed.
  • B6. Report per
    references/report-format.md
    : resolved subject (id + type) and policy chosen (+ that you asked if ambiguous); consent confirmed; export not deletion; outcome from the envelope / run status in plain terms; file location on success; poll ordering explicit (couple of polls, file only after terminal, asked if still running). State the ordering even if preconditions blocked the run.
端点、示例信封、轮询/下载流程:
references/export-and-history.md
  • B0. 解析主体。 请求中的主体信息为邮箱 / 姓名 / ID,而非
    dataSubjectId
    。需将其解析为所选策略根类型(Account / Contact / Individual / Lead / User)的记录ID——例如通过SOQL按
    Email
    查询
    Lead
    /
    Contact
    。确认该类型是策略的根类型(执行导出仅匹配主体类型的根子树——非根主体导出结果为空)。如果匹配结果为0个 / 多个 / 非根类型,停止并报告;绝不能使用猜测的ID执行导出。
  • B1. 前置条件。 策略必须处于ACTIVE状态(否则路由到工作流A)。通过
    salesforce-api-context
    解析DSR路由。
    • 明确选择策略: 指定策略→使用该策略;否则使用上下文策略;如果未建立上下文或多个ACTIVE策略可能匹配询问用户确认(例如:“为
      <subject>
      运行
      <policy>
      ——是否确认?”
      )。绝不能静默选择。
    • 权限: 如果返回
      401
      /
      403
      ,说明权限限制并停止操作——需用户权限
      Consent.CAN_EXECUTE_DSAR_POLICY
      、组织功能
      Consent.hasDsarPortability
      。即使在此错误路径下,也要明确说明轮询后下载的顺序(这是可接受的终止结果;不要盲目重试)。
  • B2. 同意检查 + 纠正删除表述(规则#2)。 如果请求将其描述为删除,首先纠正表述(导出,而非擦除)。如果授权不明确,通过
    AskUserQuestion
    询问用户
    ;授权明确→继续操作。
  • B3. 执行——信任信封内容,而非HTTP状态码。 POST执行请求,捕获运行句柄。失败的运行可能返回HTTP 201——请读取信封状态;如果状态显示失败则报告失败。
  • B4. 轮询≈2–3次后询问;仅在任务完成后下载(规则#5)。 轮询句柄(或
    DsarPolicyLog.RequestStatus
    )。早期返回
    NOT_FOUND
    / “未准备好”是正常的。如果轮询几次后仍未完成 → 停止并询问用户是否继续轮询;不要循环执行(未完成状态属于下游异步处理,非本技能可诊断)。报告运行中/已完成/出错状态。
  • B5. 下载(仅在任务成功完成后)——路径段为
    dsr
    使用
    dsar
    路径段会返回404。报告导出文件的存储位置。
  • B6. 报告参考
    references/report-format.md
    :解析后的主体(ID + 类型)及所选策略(+ 若存在歧义则说明已询问用户确认);已确认同意;导出而非删除;根据信封/运行状态用平实语言描述结果;成功时的文件位置;明确说明轮询顺序(轮询几次,仅在完成后下载,未完成时询问用户)。即使前置条件阻止了运行,也要说明该顺序。

Workflow C — History (a read)

工作流C — 历史记录(只读操作)

bash
sf data query --target-org <alias> \
  --query "SELECT Id, DsarPolicyId, RequestStatus, CreatedDate FROM DsarPolicyLog WHERE DsarPolicyId = '<POLICY_ID>' ORDER BY CreatedDate DESC"
Report prior runs (when, status); "no prior runs" is valid. On absent log /
401
/
403
/
404
, surface the raw error + prerequisite. Don't execute the policy; don't use
installListView
/ a UI list.
bash
sf data query --target-org <alias> \\
  --query "SELECT Id, DsarPolicyId, RequestStatus, CreatedDate FROM DsarPolicyLog WHERE DsarPolicyId = '<POLICY_ID>' ORDER BY CreatedDate DESC"
报告历史运行记录(时间、状态);“无历史运行记录”是有效结果。如果日志不存在 / 返回
401
/
403
/
404
,展示原始错误及前置条件。请勿执行策略;请勿使用
installListView
/ UI列表。

Workflow D — Coverage gap analysis (read-only audit)

工作流D — 覆盖缺口分析(只读审计)

"What personal data isn't covered yet?" Read-only, deterministic — surfaces candidates for the admin; classifies nothing, adds/activates nothing. Script + rubric:
references/gap-analysis-guide.md
; mechanics:
references/gap-scan.md
.
  1. Open with the plain-language method line (call #8) — one sentence in the user's terms: from the policy's objects, look one level out and flag fields that may be PII, with a reason each; the admin decides. Do not say "Workflow D", "coverage-gap audit", or "let me read the mechanics" — just state the approach in plain words and start.
  2. Read current coverage (read-only) — gaps are relative to it.
  3. Scan one hop only, and cap the breadth — describe each root + at most ~5 of its most privacy-relevant one-hop objects; depth-1 default, don't recurse. Never read a raw
    --json
    describe into the turn
    — a full describe is ~100KB and the accumulated payloads overflow the event stream, truncating the run before it writes the report (the top failure here). Project every describe to
    {name,type,label}
    first (see
    references/gap-scan.md
    ). If the policy/type can't be read (feature off — the accepted env path), stop at a single projected root describe; don't fan out. Write the report from the root + a couple of one-hop describes, name the objects you skipped, offer them via the depth gate. The written report is the deliverable — draft it early and write it; don't gather everything first.
  4. Flag candidates with a per-field reason — compliance metadata > field type > name semantics. Never "this is PII" (call #3).
  5. Report transparently — objects scanned, each candidate + reason, covered vs newly surfaced, and the one-level limit stated (even when empty).
  6. Gate depth — go deeper only on explicit confirmation (warn: large output, heavy cost).
  7. Disposition, don't mutate — ask which to add; adding routes to Workflow A (INACTIVE, stops for confirmation before reactivating — call #7).
“哪些个人数据尚未被覆盖?” 只读、确定性操作——为管理员列出候选字段;不进行分类,不添加/激活任何内容。脚本+规则:
references/gap-analysis-guide.md
;机制:
references/gap-scan.md
  1. 以平实语言的方法说明开头(规则#8)——用用户能理解的语言写一句话:从策略的对象出发,向外查看一层,标记可能包含PII的字段,每个字段给出理由;由管理员决定是否添加。禁止说“工作流D”、“覆盖缺口审计”或“让我阅读机制”——只需说明方法并开始操作。
  2. 读取当前覆盖范围(只读)——缺口是相对于当前覆盖范围而言的。
  3. 仅扫描一层,并限制广度——描述每个根对象 + 最多约5个与隐私最相关的一级关联对象;默认深度为1,请勿递归。绝不能将原始
    --json
    描述结果直接带入运行
    ——完整描述约100KB,累积的负载会溢出事件流,导致运行在生成报告前被截断(这是此处最常见的失败原因)。先将每个描述结果转换为
    {name,type,label}
    格式(参考
    references/gap-scan.md
    )。如果无法读取策略/类型(功能未启用——这是可接受的环境状态),仅转换根对象描述后停止;不要扩展。根据根对象+几个一级关联对象的描述编写报告,说明跳过的对象,通过深度限制提示用户可扩展。书面报告是交付成果——尽早起草并完成;不要先收集所有数据。
  4. 标记候选字段并给出每个字段的理由——合规元数据 > 字段类型 > 名称语义。绝不能说“这PII”(规则#3)。
  5. 透明报告——已扫描的对象、每个候选字段+理由、已覆盖vs新发现的字段,并明确说明一层限制(即使无缺口也要说明)。
  6. 深度限制——仅在用户明确确认后才深入扫描(警告:输出内容大、资源消耗高)。
  7. 处置而非修改——询问用户要添加哪些字段;添加操作路由到工作流A(INACTIVE状态,重新激活前需获取用户确认——规则#7)。

Quick rules & gotchas

快速规则与注意事项

SituationDo
Starting ANY task (even a trivial "list/does-a-policy-exist" read)FIRST scan this run's tools for a discover/describe/dispatch routing tool (project-codey/Headless 360; any
mcp__<host>__…
name — match the verb shape). Present →
discover
/
describe
/
dispatch
the
DsarPolicyManager
SOR. Do NOT open with
sf
on reflex.
sf
only when no routing tool is in reach (
sf org list
for local auth is exempt)
"Capture everything / whole graph"Exceeds caps (10/10/200) — name the cap, offer split/prune; don't walk the graph
"What PII are we missing?"Workflow D — read-only depth-1; candidates + reason; disposition to admin; add/activate nothing
Subject given by email/name, no IdResolve first (B0): query the policy's root entities; confirm a root type; 0 / many / non-root → stop
Multiple ACTIVE policies could matchConfirm which with the user before running — never silent
Run stuck
In Progress
after a couple polls
Downstream async (Tool Factory / platform), not the skill's to diagnose — report still running, ask whether to keep polling; don't loop
getfile "not ready" /
NOT_FOUND
Expected pre-terminal — poll again; not a failure
HTTP 201 on executeNot success — read the envelope status
getfile 404Segment must be
dsr
, not
dsar
Just edited an ACTIVE policyDon't auto-reactivate — stop, report, get explicit confirmation (call #6)
sf sobject describe DsarPolicy
empty
Tree is Metadata-API; only
DsarPolicyLog
answers SOQL
DsarPolicy
type absent
Surface + stop; don't fabricate
401
/
403
/
404
or missing type
Name the prerequisite and stop; no blind retries
场景操作
开始任何任务(即使是简单的“列出策略/策略是否存在”查询)首先扫描本次运行的工具,寻找discover/describe/dispatch路由工具(project-codey/Headless 360;任何
mcp__<host>__…
名称——匹配动词形态)。如果存在,
discover
/
describe
/
dispatch
DsarPolicyManager
SOR。请勿本能调用
sf
。仅当无路由工具可用时才使用
sf
sf org list
用于本地权限检查除外)
“捕获所有数据 / 整个图谱”超出上限(10/10/200)——说明上限,提供拆分/修剪方案;请勿遍历图谱
“我们遗漏了哪些PII?”运行工作流D——只读深度为1;列出候选字段+理由;处置权交由管理员;不添加/激活任何内容
主体信息为邮箱/姓名,无ID首先解析(B0):查询策略的根实体;确认根类型;结果为0个/多个/非根类型→停止
多个ACTIVE策略可能匹配运行前询问用户确认——绝不能静默选择
运行长时间处于
In Progress
状态
属于下游异步处理(Tool Factory / 平台),非本技能可诊断——报告仍在运行,询问用户是否继续轮询;不要循环执行
getfile返回“未准备好” /
NOT_FOUND
任务完成前的正常状态——再次轮询;并非失败
执行请求返回HTTP 201并非成功——读取信封状态
getfile返回404路径段必须为
dsr
,而非
dsar
刚编辑完ACTIVE状态的策略绝不自动重新激活——停止操作,报告并获取用户明确确认(规则#6)
sf sobject describe DsarPolicy
返回空
映射树是Metadata API对象;仅
DsarPolicyLog
支持SOQL查询
DsarPolicy
类型不存在
告知用户并停止;请勿伪造
返回
401
/
403
/
404
或类型不存在
说明前置条件并停止;不要盲目重试

Output (write to
${outputDir}/report.md
)

输出(写入
${outputDir}/report.md

Report only the workflow you ran; each command once; the key result in the first screenful. Be concise — state each load-bearing point (poll ordering, export-not-deletion, the one-level limit) once, not restated across an intro, an aside, and a next-steps list; keep it well under ~150 lines and don't paste exhaustive per-object dumps. On a preflight-error path (feature / policy / subject absent), name the blocker + prerequisite, state the ordering once, and stop — short. Per-workflow contracts (incl. the INACTIVE / confirmed-reactivation lifecycle and the poll ordering):
references/report-format.md
.
仅报告运行的工作流;每个命令仅展示一次;关键结果放在开头部分。保持简洁——每个核心要点(轮询顺序、导出而非删除、一层限制)仅说明一次,不要在引言、附注和后续步骤列表中重复;保持内容在~150行以内,不要粘贴详尽的对象转储。在预检查错误路径(功能/策略/主体不存在)下,说明阻塞因素+前置条件,明确说明操作顺序一次,然后停止——保持简短。各工作流的报告规范(包括INACTIVE/确认后重新激活的生命周期、轮询顺序):
references/report-format.md

Reference index

参考文档索引

FileWhen
references/headless-sor.md
MCP surface: discover→describe→dispatch the SOR, reject look-alikes,
sf
fallback
references/configure.md
Metadata shape, root/relationship resolution,
<tree.json>
input, lifecycle, multi-root
references/export-and-history.md
DSR execute/status/getfile routes, envelopes, poll sequence,
dsr
segment, history query
references/report-format.md
Per-workflow report contracts
references/gap-analysis-guide.md
Workflow D: audit script, steps, candidate-flagging rubric
references/gap-scan.md
Workflow D mechanics: one-hop enumeration, diff, depth gate, report shape
scripts/validate-policy-tree.py
Deterministic cap + devname check before authoring
文件使用场景
references/headless-sor.md
MCP界面:discover→describe→dispatch SOR,拒绝类似工具,
sf
作为fallback
references/configure.md
元数据格式、根/关系解析、
<tree.json>
输入、生命周期、多根对象
references/export-and-history.md
DSR执行/状态/getfile路由、信封、轮询流程、
dsr
路径段、历史查询
references/report-format.md
各工作流的报告规范
references/gap-analysis-guide.md
工作流D:审计脚本、步骤、候选字段标记规则
references/gap-scan.md
工作流D机制:一级关联枚举、差异对比、深度限制、报告格式
scripts/validate-policy-tree.py
编写前的确定性上限+开发名称检查
",