portaly-sentry

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Portaly Sentry — Payment Integration Health Check

Portaly Sentry — 支付集成健康检查

Use this skill to run a comprehensive security and reliability health check on a Portaly Vibe payment integration. This skill is designed for non-engineers using vibe coding tools who want to ship with confidence. Keep output human and actionable: lead with a plain-language summary and let the user drill in — reserve the 26-row technical table for when they ask for it.
This skill works alongside
portaly-payment
. It uses the same API contract as the canonical source of truth for what a correct integration looks like.
使用该技能对Portaly Vibe支付集成执行全面的安全与可靠性健康检查。本技能专为使用vibe编码工具的非工程师设计,帮助他们放心发布产品。输出内容需通俗易懂且具备可操作性:先用平实语言给出总结,让用户按需深入了解——仅在用户要求时展示包含26项检查的技术表格。
本技能与
portaly-payment
配合使用,采用与正确集成标准一致的API协议。

Quick Start

快速开始

Step 1 — Confirm integration exists

步骤1 — 确认集成存在

  • Confirm the project has a Portaly Vibe payment integration (look for
    portaly
    ,
    callbackSecret
    ,
    x-portaly-signature
    , or checkout session creation code).
  • If no integration is found, tell the user and stop.
  • 确认项目包含Portaly Vibe支付集成(查找
    portaly
    callbackSecret
    x-portaly-signature
    或结账会话创建代码)。
  • 若未找到集成,告知用户并终止流程。

Step 2 — Introduce what Sentry checks, in plain language

步骤2 — 用平实语言介绍Sentry的检查内容

Before asking anything else, show the user this intro so they understand what Sentry actually does. Do not skip this step — the first-time user has no idea what "SIG" or "SUB" means.
Template:
Portaly Sentry checks your payment integration across 3 areas:
🏦 Is the payment flow itself done right?  signatures, callbacks, subscriptions
🔐 Are your merchant credentials safe?     env vars, credential management
🛡️ Is everything else hardened?            dependencies, web security, data handling
26 checks in total, graded by severity: CRITICAL / WARNING / INFO.
在询问其他问题前,先向用户展示以下介绍,让他们了解Sentry的实际功能。请勿跳过此步骤——首次使用的用户不清楚“SIG”或“SUB”的含义。
模板:
Portaly Sentry从3个维度检查您的支付集成:
🏦 支付流程是否合规?  签名、回调、订阅
🔐 商户凭证是否安全?  环境变量、凭证管理
🛡️ 其他环节是否加固?  依赖项、Web安全、数据处理
共26项检查,按严重程度分级:CRITICAL(严重)/ WARNING(警告)/ INFO(提示)。

Step 3 — Ask which project and which scan standard

步骤3 — 询问项目和扫描标准

Do not pick a default — ask the user both questions and wait for an answer. Phrase it as a checkpoint, not a suggestion.
Template:
Two things before I start:
① Which project should I scan? (e.g. ~/gratitude-app)
② Which standard do you want?
   🚀 Pre-launch    — pass all CRITICAL
   🔧 Routine check — pass all CRITICAL + WARNING
   🏆 Gold standard — pass all 26 (including INFO)
   📄 Report only   — scan and show the report, skip the fix workflow
   ⏰ Weekly auto   — schedule a recurring scan instead of scanning now
Standard → scope mapping (agent-internal; do not show this table to the user):
User choiceReport includesBlocking severityFix workflow
🚀 Pre-launchall 26 checksCRITICAL onlyoffered
🔧 Routine checkall 26 checksCRITICAL + WARNINGoffered
🏆 Gold standardall 26 checksall severitiesoffered
📄 Report onlyall 26 checksn/anever offered
⏰ Weekly autoskip scan → jump to Step 16n/an/a
All four non-scheduled standards run all 26 checks. The first three differ only in the pass/fail threshold used in the Layer 1 summary's "Status" line (see Step 14). 📄 Report only runs the same scan but skips Layer 2 (the fix-mode prompt) and ends after Layer 3 — use it for audits, code-review handoffs, or when the user just wants to see results without committing to fixes now.
Advanced. If the user explicitly asks to scan only one category (e.g. "only scan signatures" or "re-run SIG"), accept that as a single-category mode using one of: SIG, SUB, CBK, ENV, SEC, WEB, DEP, DATA. Do not surface this as a main option — category codes overwhelm first-time users.
请勿默认选择——向用户询问这两个问题并等待回复。以确认点的方式表述,而非建议。
模板:
开始扫描前需确认两项信息:
① 要扫描哪个项目?(例如:~/gratitude-app)
② 选择扫描标准:
   🚀 预发布标准    — 所有CRITICAL项必须通过
   🔧 常规检查标准 — 所有CRITICAL + WARNING项必须通过
   🏆 黄金标准     — 通过全部26项检查(包括INFO)
   📄 仅生成报告   — 扫描并展示报告,跳过修复流程
   ⏰ 每周自动扫描 — 安排定期扫描,不立即执行
标准→范围映射(仅内部使用;请勿向用户展示此表格):
用户选择报告包含内容阻塞性严重程度修复流程
🚀 预发布标准全部26项检查仅CRITICAL提供修复
🔧 常规检查标准全部26项检查CRITICAL + WARNING提供修复
🏆 黄金标准全部26项检查所有严重程度提供修复
📄 仅生成报告全部26项检查绝不提供修复
⏰ 每周自动扫描跳过扫描→跳转至步骤16
所有四种非定期扫描标准都会执行全部26项检查。前三种标准仅在步骤14的第一层总结“状态”行中使用的通过/失败阈值不同(见步骤14)。📄仅生成报告模式执行相同扫描,但跳过第二层(修复模式提示),在第三层后结束——适用于审计、代码审查交接,或用户仅想查看结果而不立即修复的场景。
高级功能。如果用户明确要求仅扫描某一类别(例如“仅扫描签名”或“重新运行SIG”),接受此要求并使用单一类别模式,可选类别代码:SIG、SUB、CBK、ENV、SEC、WEB、DEP、DATA。请勿将此作为主要选项展示——类别代码会让首次用户感到困惑。

Prerequisites

前置条件

  • Static analysis checks (SIG, SUB, CBK, ENV, SEC, WEB, DATA) do not require credentials.
  • For DEP checks, the project must have a
    package.json
    .
  • For reporting results to Portaly, the user needs a
    PORTALY_API_KEY
    .
  • 静态分析检查(SIG、SUB、CBK、ENV、SEC、WEB、DATA)无需凭证。
  • 执行DEP检查时,项目必须包含
    package.json
  • 如需向Portaly上报结果,用户需要
    PORTALY_API_KEY

Health Check Categories

健康检查类别

SIG — Signature Verification

SIG — 签名验证

Checks that callback signature verification matches Portaly's canonical implementation.
IDCheckSeverity
SIG-001Stable JSON sort order uses
Object.entries().sort(([a],[b]) => a.localeCompare(b))
CRITICAL
SIG-002HMAC algorithm is SHA-256CRITICAL
SIG-003Timestamp replay protection rejects callbacks older than 5 minutesWARNING
SIG-004Signature comparison uses
crypto.timingSafeEqual
CRITICAL
检查回调签名验证是否符合Portaly的标准实现。
ID检查内容严重程度
SIG-001使用
Object.entries().sort(([a],[b]) => a.localeCompare(b))
实现稳定的JSON排序
CRITICAL
SIG-002HMAC算法为SHA-256CRITICAL
SIG-003时间戳重放防护拒绝超过5分钟的回调WARNING
SIG-004使用
crypto.timingSafeEqual
进行签名比较
CRITICAL

SUB — Subscription Lifecycle

SUB — 订阅生命周期

Checks that subscription identifiers are stored and used correctly across the checkout-to-cancel flow.
IDCheckSeverity
SUB-001
subscriptionId
(=
sessionId
) persisted after checkout completion
CRITICAL
SUB-002Duplicate callback handling via idempotency keyWARNING
SUB-003Cancel/resume APIs use the persisted
subscriptionId
CRITICAL
检查订阅标识符在结账至取消流程中的存储和使用是否正确。
ID检查内容严重程度
SUB-001结账完成后持久化
subscriptionId
(等于
sessionId
CRITICAL
SUB-002通过幂等键处理重复回调WARNING
SUB-003取消/恢复API使用持久化的
subscriptionId
CRITICAL

CBK — Callback Endpoint

CBK — 回调端点

Checks callback endpoint configuration and behavior.
IDCheckSeverity
CBK-001
callbackUrl
uses HTTPS
CRITICAL
CBK-002Signature verification failure is logged with diagnosticsWARNING
CBK-003Callback handler returns explicit 200 on successINFO
检查回调端点的配置和行为。
ID检查内容严重程度
CBK-001
callbackUrl
使用HTTPS
CRITICAL
CBK-002签名验证失败时记录诊断信息WARNING
CBK-003回调处理成功时返回明确的200状态码INFO

ENV — Environment & Credentials

ENV — 环境与凭证

Checks credential management and environment configuration.
IDCheckSeverity
ENV-001
.env
contains
PORTALY_API_KEY
and
PORTALY_CALLBACK_SECRET
CRITICAL
ENV-002
.gitignore
covers
.env
CRITICAL
ENV-003No API key or callback secret hardcoded in source filesCRITICAL
检查凭证管理和环境配置。
ID检查内容严重程度
ENV-001
.env
文件包含
PORTALY_API_KEY
PORTALY_CALLBACK_SECRET
CRITICAL
ENV-002
.gitignore
包含
.env
CRITICAL
ENV-003源代码中未硬编码API密钥或回调密钥CRITICAL

SEC — Security Best Practices

SEC — 安全最佳实践

Checks for security hygiene in the integration.
IDCheckSeverity
SEC-001No callback secret or API key in client-side / browser-accessible codeCRITICAL
SEC-002Raw callback body persisted for audit trailINFO
SEC-003Secrets read from environment variables (rotation-ready)INFO
SEC-004Callback endpoint has no overly permissive CORS (
Access-Control-Allow-Origin: *
)
WARNING
SEC-005Payment-related pages set
Content-Security-Policy
header
INFO
检查集成中的安全卫生情况。
ID检查内容严重程度
SEC-001客户端/浏览器可访问的代码中无回调密钥或API密钥CRITICAL
SEC-002原始回调体被持久化用于审计追踪INFO
SEC-003从环境变量读取密钥(支持轮换)INFO
SEC-004回调端点未设置过于宽松的CORS(
Access-Control-Allow-Origin: *
WARNING
SEC-005支付相关页面设置
Content-Security-Policy
INFO

WEB — Web Security Fundamentals

WEB — Web安全基础

Checks for common web security issues in payment flows.
IDCheckSeverity
WEB-001
successRedirectUrl
/
cancelRedirectUrl
validated against domain allowlist
CRITICAL
WEB-002Error responses do not expose stack traces, internal paths, or DB schemaWARNING
WEB-003Callback endpoint validates
Content-Type: application/json
WARNING
WEB-004Callback endpoint enforces request body size limitWARNING
检查支付流程中的常见Web安全问题。
ID检查内容严重程度
WEB-001
successRedirectUrl
/
cancelRedirectUrl
已针对可信域名白名单验证
CRITICAL
WEB-002错误响应未暴露堆栈跟踪、内部路径或数据库模式WARNING
WEB-003回调端点验证
Content-Type: application/json
WARNING
WEB-004回调端点强制设置请求体大小限制WARNING

DEP — Dependency Security

DEP — 依赖项安全

Checks for known vulnerabilities in project dependencies.
IDCheckSeverity
DEP-001
npm audit
/
pnpm audit
reports no critical or high CVEs
CRITICAL
DEP-002Lock file (
package-lock.json
/
pnpm-lock.yaml
) exists and is committed
WARNING
检查项目依赖项中的已知漏洞。
ID检查内容严重程度
DEP-001
npm audit
/
pnpm audit
未报告严重或高危CVE
CRITICAL
DEP-002锁文件(
package-lock.json
/
pnpm-lock.yaml
)存在且已提交
WARNING

DATA — Data Handling Security

DATA — 数据处理安全

Checks for safe data handling practices.
IDCheckSeverity
DATA-001Callback payload fields validated (type/length) before database writesWARNING
DATA-002Logs do not contain full API keys, callback secrets, or raw customer PIIWARNING
检查安全的数据处理实践。
ID检查内容严重程度
DATA-001回调负载字段在写入数据库前已验证(类型/长度)WARNING
DATA-002日志中不包含完整API密钥、回调密钥或原始客户PIIWARNING

Workflow

工作流程

Step 4 — Discover integration files

步骤4 — 发现集成文件

Search the project for files related to Portaly payment integration:
  • Files importing
    crypto
    or containing HMAC operations
  • Files containing
    portaly
    ,
    x-portaly-signature
    ,
    x-portaly-timestamp
    ,
    callbackSecret
    ,
    PORTALY_CALLBACK_SECRET
  • Callback route handlers (Express routes, Next.js API routes, Cloud Functions HTTP triggers)
  • Files containing
    subscriptionId
    ,
    sessionId
    in the context of checkout completion
  • Files containing
    successRedirectUrl
    ,
    cancelRedirectUrl
Build a file inventory and map each file to the relevant check categories.
在项目中搜索与Portaly支付集成相关的文件:
  • 导入
    crypto
    或包含HMAC操作的文件
  • 包含
    portaly
    x-portaly-signature
    x-portaly-timestamp
    callbackSecret
    PORTALY_CALLBACK_SECRET
    的文件
  • 回调路由处理器(Express路由、Next.js API路由、Cloud Functions HTTP触发器)
  • 在结账完成上下文中包含
    subscriptionId
    sessionId
    的文件
  • 包含
    successRedirectUrl
    cancelRedirectUrl
    的文件
构建文件清单,并将每个文件映射到相关检查类别。

Step 5 — Run SIG checks

步骤5 — 执行SIG检查

For each signature-related file:
  1. Check sort order pattern — compare against canonical implementation in
    ../portaly-payment/scripts/sign_callback.mjs
    .
  2. Check HMAC algorithm — verify
    createHmac('sha256', ...)
    .
  3. Check timestamp validation — look for comparison of
    x-portaly-timestamp
    against current time with a 5-minute window.
  4. Check comparison method — verify
    crypto.timingSafeEqual
    is used, not
    ===
    or
    ==
    .
Reference:
scripts/check_signature_sort.mjs
can automate this step.
对于每个签名相关文件:
  1. 检查排序模式——与
    ../portaly-payment/scripts/sign_callback.mjs
    中的标准实现对比。
  2. 检查HMAC算法——验证使用
    createHmac('sha256', ...)
  3. 检查时间戳验证——查找将
    x-portaly-timestamp
    与当前时间对比并设置5分钟窗口的逻辑。
  4. 检查比较方法——验证使用
    crypto.timingSafeEqual
    而非
    ===
    ==
参考:
scripts/check_signature_sort.mjs
可自动化此步骤。

Step 6 — Run SUB checks

步骤6 — 执行SUB检查

Trace the subscription ID lifecycle:
  1. In the callback handler, after
    status === 'completed'
    , check what gets persisted. The stored value should be
    sessionId
    (which equals
    subscriptionId
    per Portaly's current contract).
  2. Check for idempotency — does the handler check if this
    sessionId
    was already processed before fulfilling?
  3. Trace the cancel/resume code path — verify it reads the same
    subscriptionId
    field that the callback wrote and passes it to
    /subscriptions/{subscriptionId}/cancel
    or
    /resume
    .
Reference:
scripts/check_subscription_lifecycle.mjs
can automate this step.
追踪订阅ID的生命周期:
  1. 在回调处理器中,当
    status === 'completed'
    后,检查持久化的内容。存储的值应为
    sessionId
    (根据Portaly当前协议,其等于
    subscriptionId
    )。
  2. 检查幂等性——处理器是否在执行前检查该
    sessionId
    是否已处理过?
  3. 追踪取消/恢复代码路径——验证其读取回调写入的同一
    subscriptionId
    字段,并将其传递给
    /subscriptions/{subscriptionId}/cancel
    /resume
参考:
scripts/check_subscription_lifecycle.mjs
可自动化此步骤。

Step 7 — Run CBK checks

步骤7 — 执行CBK检查

  1. Check if
    callbackUrl
    is constructed with
    https://
    .
  2. Check the signature verification failure branch — does it log diagnostic info (timestamp, payload hash, expected vs actual)?
  3. Check that the success branch returns an explicit
    200
    status.
  1. 检查
    callbackUrl
    是否使用
    https://
    构建。
  2. 检查签名验证失败分支——是否记录诊断信息(时间戳、负载哈希、预期值与实际值)?
  3. 检查成功分支是否返回明确的
    200
    状态码。

Step 8 — Run ENV checks

步骤8 — 执行ENV检查

  1. Read
    .env
    (or
    .env.example
    ,
    .env.local
    ) — check for
    PORTALY_API_KEY
    and
    PORTALY_CALLBACK_SECRET
    .
  2. Read
    .gitignore
    — check that
    .env
    is listed.
  3. Grep source files (excluding
    node_modules
    ,
    .env
    ) for literal
    pcs_live_
    ,
    pcs_test_
    , or any string that looks like a callback secret.
  1. 读取
    .env
    (或
    .env.example
    .env.local
    )——检查是否包含
    PORTALY_API_KEY
    PORTALY_CALLBACK_SECRET
  2. 读取
    .gitignore
    ——检查是否包含
    .env
  3. 在源代码中搜索(排除
    node_modules
    .env
    )字面量
    pcs_live_
    pcs_test_
    或任何类似回调密钥的字符串。

Step 9 — Run SEC checks

步骤9 — 执行SEC检查

  1. Check for API key or callback secret in files under directories typically served to the browser (
    src/
    ,
    public/
    ,
    app/
    ,
    pages/
    for client components). Watch for
    NEXT_PUBLIC_
    prefixed env vars containing secrets.
  2. Check if the raw callback body is saved to the database for auditing.
  3. Verify secrets are read from
    process.env
    or equivalent, not hardcoded.
  4. Check for CORS middleware on the callback endpoint — flag
    Access-Control-Allow-Origin: *
    .
  5. Check for CSP headers on success/cancel redirect pages.
  1. 检查浏览器可访问目录(
    src/
    public/
    app/
    、客户端组件的
    pages/
    )下的文件中是否存在API密钥或回调密钥。注意包含
    NEXT_PUBLIC_
    前缀的环境变量是否包含密钥。
  2. 检查原始回调体是否保存到数据库用于审计。
  3. 验证密钥从
    process.env
    或等效方式读取,而非硬编码。
  4. 检查回调端点的CORS中间件——标记
    Access-Control-Allow-Origin: *
  5. 检查成功/取消重定向页面是否设置CSP头。

Step 10 — Run WEB checks

步骤10 — 执行WEB检查

  1. Check if
    successRedirectUrl
    and
    cancelRedirectUrl
    are validated against an allowlist of trusted domains before being used in redirects.
  2. Check error handling in the callback route — ensure
    catch
    blocks do not send full error stacks in the response body.
  3. Check that the callback endpoint validates
    Content-Type
    header.
  4. Check for body parser size limits (e.g.,
    express.json({ limit: '1mb' })
    or equivalent).
  1. 检查
    successRedirectUrl
    cancelRedirectUrl
    在用于重定向前是否已针对可信域名白名单验证。
  2. 检查回调路由中的错误处理——确保
    catch
    块不在响应体中发送完整错误堆栈。
  3. 检查回调端点是否验证
    Content-Type
    头。
  4. 检查是否设置了解析器大小限制(例如
    express.json({ limit: '1mb' })
    或等效配置)。

Step 11 — Run DEP checks

步骤11 — 执行DEP检查

  1. If
    package.json
    exists, run
    npm audit --json
    or
    pnpm audit --json
    and parse the output for critical/high severity vulnerabilities.
  2. Check if
    package-lock.json
    or
    pnpm-lock.yaml
    exists and is not in
    .gitignore
    .
  1. 如果存在
    package.json
    ,运行
    npm audit --json
    pnpm audit --json
    并解析输出,查找严重或高危漏洞。
  2. 检查
    package-lock.json
    pnpm-lock.yaml
    是否存在且未包含在
    .gitignore
    中。

Step 12 — Run DATA checks

步骤12 — 执行DATA检查

  1. Check if callback payload fields are validated before database writes (type checks, length limits, sanitization).
  2. Grep log statements (
    console.log
    ,
    console.error
    ,
    logger.
    ) for potential secret or PII exposure — flag any that log the full callback payload, API key, or callback secret.
  1. 检查回调负载字段在写入数据库前是否已验证(类型检查、长度限制、清理)。
  2. 在日志语句(
    console.log
    console.error
    logger.
    )中搜索潜在的密钥或PII泄露——标记任何记录完整回调负载、API密钥或回调密钥的日志。

Step 13 — Sync results to Portaly (optional)

步骤13 — 将结果同步到Portaly(可选)

After running all checks but before presenting the summary, offer to sync the scan to the user's Portaly dashboard. Doing this now means Step 14's Layer 1 summary can include a shareable report link.
There are two transports — prefer MCP when available:
Path A — MCP (preferred, zero extra config). If the agent is connected to Vibe MCP, the
vibe_report_health_check
tool is available. It uses the agent's existing MCP connection — no
PORTALY_API_KEY
needed. Briefly ask consent, then call the tool with the scan payload. Capture
reportId
and
dashboardUrl
from the response and use
reportId
as
{scan_id}
in the Layer 1 dashboard link. See
references/health-check-contract.md
§ "MCP reporting" for the input schema.
Path B — REST API (fallback). When MCP is not connected and the user has
PORTALY_API_KEY
set in their environment, fall back to running
scripts/report.mjs
— it reads the key from
process.env.PORTALY_API_KEY
and POSTs to
https://portaly.ai/api/creator-subscription/health-check-reports
for you. Prefer this over hand-rolling a
curl
/
fetch
with the key inline. Capture
reportId
from the script's stdout. See
references/health-check-contract.md
§ "Report API Contract" for the full request/response schema.
Rules:
  • Do not call either path without explicit user consent.
  • If both paths are unavailable (no MCP, no key) or the call fails (e.g., 404 on REST), skip the sync silently and continue to Step 14 without a dashboard link. Do not block the summary on this.
  • Do not call both paths for the same scan — pick one.
在完成所有检查但展示总结前,询问用户是否要将扫描结果同步到其Portaly仪表板。此时同步可让步骤14的第一层总结包含可分享的报告链接。
有两种传输方式——优先使用MCP:
路径A — MCP(优先,无需额外配置)。如果代理已连接到Vibe MCP,则
vibe_report_health_check
工具可用。它使用代理现有的MCP连接——无需
PORTALY_API_KEY
。简要询问用户同意后,调用该工具并传入扫描负载。从响应中捕获
reportId
dashboardUrl
,并在第一层仪表板链接中使用
reportId
作为
{scan_id}
。参考
references/health-check-contract.md
§ "MCP reporting"获取输入 schema。
路径B — REST API(备选)。当未连接MCP且用户环境中已设置
PORTALY_API_KEY
时,退而使用
scripts/report.mjs
——它从
process.env.PORTALY_API_KEY
读取密钥并POST到
https://portaly.ai/api/creator-subscription/health-check-reports
。优先使用此方式而非手动编写包含密钥的
curl
/
fetch
。从脚本标准输出中捕获
reportId
。参考
references/health-check-contract.md
§ "Report API Contract"获取完整请求/响应schema。
规则:
  • 未经用户明确同意,请勿调用任何路径。
  • 如果两种路径都不可用(无MCP、无密钥)或调用失败(例如REST返回404),静默跳过同步并继续到步骤14,不展示仪表板链接。请勿因同步问题阻塞总结展示。
  • 请勿对同一扫描调用两种路径——选择其一。

Step 14 — Present the summary (not the full table)

步骤14 — 展示总结(而非完整表格)

The first thing the user sees must be a plain-language summary, not a 26-row table. The full technical report lives on the dashboard — only show it locally when the user picks
[C]
, when the user is in 📄 Report only mode, or when dashboard reporting is unavailable.
Output up to three layers, in this order (📄 Report only mode emits Layer 1 + Layer 3 only — see below):
用户首先看到的必须是平实语言的总结,而非包含26行的表格。完整技术报告在仪表板上——仅当用户选择
[C]
、处于📄仅生成报告模式,或仪表板报告不可用时,才在本地展示。
按以下顺序输出最多三层内容(📄仅生成报告模式仅输出第一层 + 第三层——见下文):

Layer 1 — Plain-language summary (always show)

第一层 — 平实语言总结(始终展示)

Load titles from
references/fix-explanations.md
— do not invent new phrasing. Compute the health score from the per-check results using the formula in
references/health-check-contract.md
§ "Health Score Formula" — the same number the dashboard shows.
Template:
📊 Payment integration health check — {projectName}
   Health score: {score}/100  ({band: Healthy | Needs attention | At risk})

🟢 Passing   {passedCount} checks    looking good
🟡 Review    {warnedCount} warnings  take a look this week
🔴 Critical  {failedCount} blockers  must fix before launch

Status: {status_line}

Top {min(3, failures)} things to fix:
1. {plain title from fix-explanations.md} ({ID})
2. ...
3. ...

🔗 Full report (all 26 checks, fix guidance, history)
https://portaly.ai/dashboard/sentry-scans/{scan_id}
Score banding (must match the dashboard):
ScoreBand
90–100Healthy
70–89Needs attention
0–69At risk
{status_line}
is decided by the scan standard chosen in Step 3 (independent of score — the score is informational, the standard gates launch):
StandardCondition for "safe to launch"
🚀 Pre-launch0 CRITICAL failures
🔧 Routine check0 CRITICAL and 0 WARNING failures
🏆 Gold standard0 failures across all 26 checks
Use
✅ Safe to launch
or
❌ Not safe to launch yet
— nothing in between. If the Step 13 sync was skipped and there is no
scan_id
, drop the whole
🔗 Full report
block (both the label line and the URL line); do not show a broken or placeholder link.
For 📄 Report only, omit the
Status:
line entirely (there is no launch gate in this mode) and replace it with
Mode: 📄 Report only — fix workflow disabled
. Everything else in Layer 1 stays the same.
references/fix-explanations.md
加载标题——请勿自行创造表述。使用
references/health-check-contract.md
§ "Health Score Formula"中的公式根据每项检查结果计算健康分数——与仪表板显示的分数一致。
模板:
📊 支付集成健康检查 — {projectName}
   健康分数: {score}/100  ({等级: 健康 | 需要关注 | 存在风险})

🟢 通过    {passedCount}项检查    表现良好
🟡 待审核  {warnedCount}项警告    本周内处理
🔴 严重问题 {failedCount}项阻塞    发布前必须修复

状态: {status_line}

最需修复的{min(3, failures)}个问题:
1. {来自fix-explanations.md的平实标题} ({ID})
2. ...
3. ...

🔗 完整报告(全部26项检查、修复指南、历史记录)
https://portaly.ai/dashboard/sentry-scans/{scan_id}
分数等级(必须与仪表板一致):
分数等级
90–100健康
70–89需要关注
0–69存在风险
{status_line}
由步骤3选择的扫描标准决定(与分数无关——分数仅作参考,标准决定是否可发布):
标准"可安全发布"条件
🚀 预发布标准0项CRITICAL失败
🔧 常规检查标准0项CRITICAL 0项WARNING失败
🏆 黄金标准26项检查全部通过
使用
✅ 可安全发布
❌ 暂不可安全发布
——无中间状态。如果步骤13同步被跳过且无
scan_id
,则删除整个
🔗 完整报告
块(包括标签行和URL行);请勿展示无效或占位链接。
对于📄仅生成报告模式,完全省略
Status:
行(此模式无发布门限),替换为
模式: 📄 仅生成报告 — 修复流程已禁用
。第一层的其他内容保持不变。

Layer 2 — Fix mode choice (show right after summary, except in 📄 Report only)

第二层 — 修复模式选择(总结后立即展示,📄仅生成报告模式除外

In 📄 Report only mode, skip Layer 2 entirely and go straight to Layer 3. Do not render the
[A] / [B] / [C]
prompt — the user has already opted out of fixes.
Template:
─────────────────────────────────────
Want to start fixing now?
[A] Yes, walk me through all of them in order (recommended)
[B] Just the 🔴 critical ones (fastest path to launch)
[C] Show me the full report first
The user's answer routes to:
  • [A] → Interactive Fix Workflow with all failures, ordered CRITICAL → WARNING → INFO
  • [B] → Interactive Fix Workflow with CRITICAL failures only
  • [C] → Layer 3
在📄仅生成报告模式下,完全跳过第二层直接进入第三层。请勿显示
[A] / [B] / [C]
提示——用户已选择不修复。
模板:
─────────────────────────────────────
是否现在开始修复?
[A] 是,按顺序引导我修复所有问题(推荐)
[B] 仅修复🔴严重问题(最快发布路径)
[C] 先展示完整报告
用户的回复将导向:
  • [A] → 交互式修复流程,处理所有失败项,按严重程度排序(CRITICAL → WARNING → INFO)
  • [B] → 交互式修复流程,仅处理CRITICAL失败项
  • [C] → 第三层

Layer 3 — Full technical report (on [C], in 📄 Report only mode, or when dashboard reporting is unavailable)

第三层 — 完整技术报告(选择[C]时、📄仅生成报告模式下,或仪表板报告不可用时)

Render the full 26-row table, grouped by category. Format:
undefined
按类别分组展示完整的26行表格。格式:
undefined

Portaly Sentry — Health Check Report

Portaly Sentry — 健康检查报告

Project: {project_name} | Scan: {ISO timestamp} | Mode: {manual|scheduled}
项目: {project_name} | 扫描时间: {ISO时间戳} | 模式: {手动|定期}

SIG — Signature Verification

SIG — 签名验证

#CheckSeverityStatus
SIG-001Stable JSON sort orderCRITICAL[PASS]
............
#检查内容严重程度状态
SIG-001稳定JSON排序CRITICAL[PASS]
............

SUB — Subscription Lifecycle

SUB — 订阅生命周期

#CheckSeverityStatus
............
(repeat for CBK / ENV / SEC / WEB / DEP / DATA)

Summary: X/26 passed | Y CRITICAL failures | Z warnings | W skipped
#检查内容严重程度状态
............
(CBK / ENV / SEC / WEB / DEP / DATA类别重复上述格式)

总结: X/26通过 | Y项CRITICAL失败 | Z项警告 | W项跳过

Fix: {ID} — {Check Name}

修复: {ID} — {检查名称}

File: {file_path}:{line} {description of the issue} {code diff showing the fix}
undefined
文件: {file_path}:{line} {问题描述} {显示修复的代码差异}
undefined

Step 15 — Interactive Fix Workflow (per-item confirmation)

步骤15 — 交互式修复流程(逐项确认)

Enter this workflow only after the user explicitly picks [A] (fix all) or [B] (fix CRITICAL only) from Layer 2. For each failure, in order of severity (CRITICAL → WARNING → INFO), present exactly one item at a time and wait for confirmation before touching any file.
In 📄 Report only mode this step is unreachable by design — Layer 2 is never shown, so [A]/[B] are never picked. If the user later changes their mind and asks to start fixing, treat that as a new request and re-prompt with the Layer 2 choices before entering this workflow.
仅当用户明确从第二层选择**[A](修复全部)或[B]**(仅修复CRITICAL)后,才进入此流程。对于每个失败项,按严重程度顺序(CRITICAL → WARNING → INFO),每次仅展示一项,等待用户确认后再修改文件。
📄仅生成报告模式下,此步骤不可达——第二层从未显示,因此[A]/[B]从未被选择。如果用户之后改变主意并要求开始修复,将其视为新请求,在进入此流程前重新提示第二层选择。

Per-item template

逐项模板

Render the block below for each failure. All plain-language copy comes from
references/fix-explanations.md
— do not paraphrase on the fly. Keep IDs, file paths, code in the diff, and the
[Y]/[N]/[?]/[STOP]
keys as-is.
Template:
🔴 Item {n} of {m}        | Progress {progress_bar} {percent}%
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Fix: {plain title} ({ID})

📍 Which file?
{file_path} ({change summary, e.g. "add 1 import, change 3 lines"})

❓ Why does this matter?
{why it matters, from fix-explanations.md}

🔧 Preview:
{unified diff, - old / + new}

✅ Affects:       {affects, from fix-explanations.md}
✅ Doesn't affect: {doesn't affect, from fix-explanations.md}
─────────────────────────────────────
Apply this fix?
[Y] Go ahead, apply it
[N] Skip this one
[?] I'd like to understand more first
[STOP] Pause here, I'll come back later
为每个失败项渲染以下内容。所有平实语言文案来自
references/fix-explanations.md
——请勿即兴改写。保持ID、文件路径、代码差异中的代码,以及
[Y]/[N]/[?]/[STOP]
选项不变。
模板:
🔴 第{n}项,共{m}项        | 进度 {progress_bar} {percent}%
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
修复: {平实标题} ({ID})

📍 涉及文件:
{file_path} ({变更摘要,例如"添加1个导入,修改3行"})

❓ 为什么这很重要?
{来自fix-explanations.md的原因说明}

🔧 预览:
{统一差异格式,- 旧代码 / + 新代码}

✅ 影响范围:       {来自fix-explanations.md的影响说明}
✅ 不影响: {来自fix-explanations.md的非影响说明}
─────────────────────────────────────
是否应用此修复?
[Y] 确认,应用修复
[N] 跳过此项
[?] 我想了解更多细节
[STOP] 暂停,稍后再继续

Rules

规则

  • One item at a time. Never batch multiple fixes into one confirmation. Even if [B] has 3 CRITICAL items, ask Y/N for each.
  • Match severity icon to the header: 🔴 for CRITICAL, 🟡 for WARNING, ⚪ for INFO.
  • Progress bar: use
    filled and
    empty, 7 blocks total. Example at 3/7:
    ▓▓▓░░░░
    .
  • Use the user's own code style in the diff. Match their module system (ESM vs CommonJS), variable names, and framework idioms. Pull canonical fix patterns from
    references/common-pitfalls.md
    and
    ../portaly-payment/scripts/sign_callback.mjs
    , then adapt to the user's style.
  • Never show raw CRITICAL/WARNING/INFO labels in user-facing text. Use natural phrasing like "Critical / Should fix / Nice to have", and let the 🔴/🟡/⚪ icons carry severity visually.
  • 逐项处理。切勿将多个修复合并为一次确认。即使[B]有3项CRITICAL问题,也要逐项询问Y/N。
  • 标题图标匹配严重程度:🔴对应CRITICAL,🟡对应WARNING,⚪对应INFO。
  • 进度条:使用
    填充,
    空白,共7个区块。示例:3/7进度为
    ▓▓▓░░░░
  • 代码差异匹配用户代码风格。匹配其模块系统(ESM vs CommonJS)、变量名和框架习惯。从
    references/common-pitfalls.md
    ../portaly-payment/scripts/sign_callback.mjs
    获取标准修复模式,然后适配用户风格。
  • 用户可见文本中请勿显示原始CRITICAL/WARNING/INFO标签。使用自然表述如“严重问题 / 建议修复 / 优化项”,并通过🔴/🟡/⚪图标直观展示严重程度。

Handling each response

回复处理

Match the user's reply to intent rather than an exact string. The key-letter triggers are canonical; equivalent words in English or the user's own language count as the same intent.
IntentCanonical triggerAction
Apply
[Y]
(or "yes" / "apply" / "ok" / equivalent)
Apply the edit, confirm success in one line (e.g.
✅ Applied {ID}
), then move to item n+1.
Skip
[N]
(or "skip" / "no" / equivalent)
Do not modify the file. Mark as
⏭️ Skipped {ID}
and move to item n+1.
Explain
[?]
(or "why" / "tell me more" / equivalent)
Load the corresponding pitfall entry from
references/common-pitfalls.md
(wrong vs correct implementation with explanation). After explaining, re-prompt with the same Y/N/?/STOP choices — do not re-render the full template.
Stop
[STOP]
(or "pause" / "later" / equivalent)
Stop immediately. Show a resume summary:
Applied X / Skipped Y / Remaining Z. Say "resume fixing" any time and I'll pick up at item {n}.
Do not proceed.
根据用户回复的意图而非精确字符串匹配。关键字母触发为标准;英文或用户本地语言的等效表述视为同一意图。
意图标准触发词操作
应用
[Y]
(或"yes" / "apply" / "ok" / 等效表述)
应用修改,用一行确认成功(例如
✅ 已应用{ID}
),然后处理第n+1项。
跳过
[N]
(或"skip" / "no" / 等效表述)
不修改文件。标记为
⏭️ 已跳过{ID}
,然后处理第n+1项。
解释
[?]
(或"why" / "tell me more" / 等效表述)
references/common-pitfalls.md
加载对应的常见问题条目(错误与正确实现及说明)。解释后,重新提示相同的Y/N/?/STOP选项——无需重新渲染完整模板。
停止
[STOP]
(或"pause" / "later" / 等效表述)
立即停止。展示恢复总结:
已应用X项 / 已跳过Y项 / 剩余Z项。随时说"恢复修复",我将从第{n}项继续。
不再继续处理。

After the last item

最后一项处理完成后

Template:
🎉 Fix session complete
✅ Applied: {X}
⏭️ Skipped: {Y}
─────────────────────────────────────
Suggested next steps:
1. Run your usual tests or try a checkout end-to-end
2. Re-run Sentry to confirm everything passes now
3. If you have a Portaly API key, sync the results to your dashboard
模板:
🎉 修复会话完成
✅ 已应用: {X}项
⏭️ 已跳过: {Y}项
─────────────────────────────────────
建议后续步骤:
1. 运行常规测试或尝试端到端结账流程
2. 重新运行Sentry确认所有问题已解决
3. 如果您有Portaly API密钥,将结果同步到仪表板

Step 16 — Set up automated scanning (optional)

步骤16 — 设置自动扫描(可选)

Three options, from simplest to most rigorous. Present all three and let the user choose.
Option A — GitHub Actions (recommended for any project with a GitHub repo)
Tell the user to create
.github/workflows/portaly-sentry.yml
with the template in
references/ci-setup-guide.md
. Then add
PORTALY_API_KEY
as a GitHub repository secret. This runs on every push to main AND weekly on Monday — blocks merges if CRITICAL issues are found.
Option B — Pre-push git hook (local machine enforcement)
Run once to install:
bash
cat > .git/hooks/pre-push << 'EOF'
#!/bin/sh
set -e
node "$(git rev-parse --show-toplevel)/.claude/skills/portaly-sentry/scripts/report.mjs" \
  --dir "$(git rev-parse --show-toplevel)" --fail-on critical
EOF
chmod +x .git/hooks/pre-push
Option C — Automated script runner via
scripts/report.mjs
For any CI system or scheduled task, point at the automation script directly. The script reads
PORTALY_API_KEY
from the environment — set it through the CI's secret store, your shell profile, or a
.env
loader rather than inlining the value.
bash
undefined
提供三种选项,从简单到严格。展示所有选项让用户选择。
选项A — GitHub Actions(推荐给所有GitHub仓库项目)
告知用户创建
.github/workflows/portaly-sentry.yml
,使用
references/ci-setup-guide.md
中的模板。然后将
PORTALY_API_KEY
添加为GitHub仓库密钥。此配置会在每次推送到main分支时运行,且每周一自动运行——如果发现CRITICAL问题,将阻止合并。
选项B — Git预推送钩子(本地机器强制执行)
运行一次完成安装:
bash
cat > .git/hooks/pre-push << 'EOF'
#!/bin/sh
set -e
node "$(git rev-parse --show-toplevel)/.claude/skills/portaly-sentry/scripts/report.mjs" \
  --dir "$(git rev-parse --show-toplevel)" --fail-on critical
EOF
chmod +x .git/hooks/pre-push
选项C — 通过
scripts/report.mjs
自动脚本运行
对于任何CI系统或定时任务,直接指向自动化脚本。脚本从环境读取
PORTALY_API_KEY
——通过CI密钥存储、shell配置文件或
.env
加载器设置,而非硬编码值。
bash
undefined

PORTALY_API_KEY exported via CI secret / shell / .env

PORTALY_API_KEY通过CI密钥/shell/.env导出

node .claude/skills/portaly-sentry/scripts/report.mjs
--dir . --scan-type scheduled --fail-on critical

`--fail-on critical` makes the command exit 1 when CRITICAL issues are found,
which any CI system will treat as a build failure.

See `references/ci-setup-guide.md` for the full CLI reference and setup instructions.
node .claude/skills/portaly-sentry/scripts/report.mjs
--dir . --scan-type scheduled --fail-on critical

`--fail-on critical`参数会在发现CRITICAL问题时让命令以1退出,任何CI系统都会将其视为构建失败。

参考`references/ci-setup-guide.md`获取完整CLI参考和设置说明。

Output Style

输出风格

  • Lead with the plain-language summary (Layer 1), not the table. The 26-row table is Layer 3, shown only on request.
  • Use the plain title from
    references/fix-explanations.md
    when naming a failed check — never surface raw IDs like "SIG-004" as the headline. Put the ID in parentheses after the title.
  • Use
    [PASS]
    ,
    [FAIL]
    ,
    [WARN]
    ,
    [SKIP]
    status indicators only inside Layer 3 tables.
  • Group Layer 3 checks by category (SIG, SUB, CBK, ENV, SEC, WEB, DEP, DATA).
  • Per-failure fix instructions belong in the Interactive Fix Workflow (one at a time, with explicit confirmation), not in a dumped list after the table.
  • Static analysis is read-only. Only enter fix mode after the user picks [A] or [B].
  • 先展示平实语言总结(第一层),而非表格。26行表格属于第三层,仅在用户要求时展示。
  • 命名失败检查时,使用
    references/fix-explanations.md
    中的平实标题——切勿将“SIG-004”等原始ID作为标题。将ID放在标题后的括号中。
  • 仅在第三层表格中使用
    [PASS]
    [FAIL]
    [WARN]
    [SKIP]
    状态标识。
  • 第三层检查按类别分组(SIG、SUB、CBK、ENV、SEC、WEB、DEP、DATA)。
  • 每项失败的修复说明属于交互式修复流程(逐项展示,需明确确认),而非表格后的批量列表。
  • 静态分析为只读模式。仅在用户选择[A]或[B]后进入修复模式。

Preferred Response Shape

首选响应结构

Standard modes (🚀 Pre-launch / 🔧 Routine check / 🏆 Gold standard):
  1. Plain-language summary with 🔴/🟡/⚪ counts, status line, TOP 3 failures, dashboard link (Layer 1)
  2. Fix mode choice prompt: [A] / [B] / [C] (Layer 2)
  3. Then one of:
    • [A] or [B] → enter Interactive Fix Workflow (one failure at a time)
    • [C] → show full Layer 3 report grouped by category
  4. Optional: report-to-Portaly confirmation
📄 Report only mode:
  1. Plain-language summary (Layer 1, with
    Mode:
    line in place of
    Status:
    )
  2. Full Layer 3 report grouped by category
  3. Stop. Do not show Layer 2, do not enter the Interactive Fix Workflow.
  4. Optional: report-to-Portaly confirmation
标准模式(🚀预发布 / 🔧常规检查 / 🏆黄金标准):
  1. 平实语言总结,包含🔴/🟡/⚪计数、状态行、前3个失败项、仪表板链接(第一层)
  2. 修复模式选择提示:[A] / [B] / [C](第二层)
  3. 然后进入以下之一:
    • [A]或[B] → 进入交互式修复流程(逐项处理失败项)
    • [C] → 展示按类别分组的完整第三层报告
  4. 可选:向Portaly上报确认
📄仅生成报告模式:
  1. 平实语言总结(第一层,用
    Mode:
    行替换
    Status:
    行)
  2. 按类别分组的完整第三层报告
  3. 停止。不展示第二层,不进入交互式修复流程。
  4. 可选:向Portaly上报确认

Guardrails

防护规则

  • Read-only until the user enters fix mode. Discovery, scanning, and the Layer 1/3 reports must not touch user code. Only after the user picks
    [A]
    or
    [B]
    in Layer 2 may you enter the Interactive Fix Workflow, and within it only apply an edit after a
    [Y]
    for that specific item. Never batch-apply multiple fixes from a single confirmation.
  • 📄 Report only stays read-only, period. When the user picks Report only in Step 3, do not show Layer 2 and do not enter the Interactive Fix Workflow — even if the report surfaces CRITICAL failures. If the user later asks to fix, treat that as a new request and re-prompt with [A]/[B]/[C] before applying anything.
  • Don't surface secret values in your own output. When generating example commands, headers, snippets, logs, PR/commit content, or anything else you write, refer to the credential by variable name only (
    $PORTALY_API_KEY
    ) — never with a literal value like
    pcs_live_...
    . Prefer
    scripts/report.mjs
    or the MCP
    vibe_report_health_check
    tool over hand-rolling
    curl
    /
    fetch
    with the key in the header. If a check surfaces a secret found in the user's source, mask it as
    ***
    before displaying. Helping the user when they explicitly provide a key (e.g. "save this to
    .env
    ", "test this key") is fine — this rule is about what you generate on your own initiative.
  • Cross-reference portaly-payment. Load
    ../portaly-payment/references/api-contract.md
    for the authoritative callback verification spec and subscription lifecycle contract.
  • Do not assume the user's stack. Check for Express, Next.js (App Router / Pages Router), Cloud Functions, Fastify, or vanilla Node.js before recommending fixes.
  • Match the user's code style. When recommending fixes, generate code that matches the user's existing patterns, variable naming, and module system (ESM vs CommonJS).
  • If no integration is found, stop. Tell the user the project does not appear to have a Portaly payment integration and ask if they want to set one up using
    portaly-payment
    .
  • Report API is optional. Do not call the health-check report API without user consent. If the API returns 404, skip silently and show results locally.
  • DEP checks require package.json. If no
    package.json
    exists, skip DEP checks and mark them as
    [SKIP]
    .
  • Windows encoding. On Windows, run
    chcp 65001
    before any API calls containing non-ASCII text.
  • 进入修复模式前为只读。发现、扫描及第一层/第三层报告不得修改用户代码。仅在用户从第二层选择
    [A]
    [B]
    后,才可进入交互式修复流程,且仅在用户对特定项选择
    [Y]
    后才可应用修改。切勿通过一次确认批量应用多个修复。
  • 📄仅生成报告模式始终保持只读。当用户在步骤3选择仅生成报告时,不展示第二层,不进入交互式修复流程——即使报告发现CRITICAL问题。如果用户之后要求修复,将其视为新请求,在应用任何修改前重新提示[A]/[B]/[C]选择。
  • 输出中请勿暴露密钥值。生成示例命令、头信息、代码片段、日志、PR/提交内容或任何其他内容时,仅通过变量名引用凭证(
    $PORTALY_API_KEY
    )——切勿使用
    pcs_live_...
    等字面量值。优先使用
    scripts/report.mjs
    或MCP的
    vibe_report_health_check
    工具,而非手动编写包含密钥的
    curl
    /
    fetch
    。如果检查在用户源代码中发现密钥,在显示前将其掩码为
    ***
    。当用户明确提供密钥时(例如“保存到
    .env
    ”、“测试此密钥”)提供帮助是允许的——本规则针对主动生成的内容。
  • 交叉参考portaly-payment。加载
    ../portaly-payment/references/api-contract.md
    获取权威的回调验证规范和订阅生命周期协议。
  • 请勿假设用户的技术栈。在推荐修复前,检查是否使用Express、Next.js(App Router / Pages Router)、Cloud Functions、Fastify或原生Node.js。
  • 匹配用户代码风格。推荐修复时,生成与用户现有模式、变量命名和模块系统(ESM vs CommonJS)一致的代码。
  • 未找到集成则停止。告知用户项目似乎不包含Portaly支付集成,并询问是否要使用
    portaly-payment
    设置集成。
  • 上报API为可选。未经用户同意,请勿调用健康检查上报API。如果API返回404,静默跳过并在本地展示结果。
  • DEP检查需要package.json。如果不存在
    package.json
    ,跳过DEP检查并标记为
    [SKIP]
  • Windows编码。在Windows上,运行包含非ASCII文本的API调用前,执行
    chcp 65001

Resources

资源

  • references/health-check-contract.md
    Use for the full checklist item definitions, severity levels, pass/fail criteria, and the report API contract.
  • references/common-pitfalls.md
    Use for detailed descriptions of known bugs found in real integrations, with wrong vs correct implementations and detection methods. Load this when a user picks
    [?]
    (explain more) in the Interactive Fix Workflow.
  • references/fix-explanations.md
    Use for user-facing plain-language copy of all 26 checks: plain title, why it matters, affects, doesn't affect. Load during Layer 1 summary rendering and during each Interactive Fix Workflow item. Do not paraphrase on the fly — keep the canonical phrasing consistent across summary and per-item views.
  • scripts/report.mjs
    Use for fully automated CI/CD scanning — runs all 26 checks, prints a formatted report, and POSTs results to portaly.ai. Accepts
    --fail-on critical
    for CI exit code control.
  • scripts/computeHealthScore.mjs
    Canonical implementation of the 0–100 health score formula. Imported by
    report.mjs
    and mirrored by the Vibe dashboard so the skill terminal and the dashboard always show the same number.
  • scripts/check_signature_sort.mjs
    Use for automated signature sort pattern verification across project files. Called internally by
    report.mjs
    .
  • scripts/check_subscription_lifecycle.mjs
    Use for automated subscription ID lifecycle tracing. Called internally by
    report.mjs
    .
  • references/ci-setup-guide.md
    Use when the user wants to set up GitHub Actions, pre-push hooks, or npm scripts for automated scanning.
  • Cross-reference:
    ../portaly-payment/scripts/sign_callback.mjs
    Canonical Portaly callback signature implementation. Use as the reference for what correct looks like.
  • Cross-reference:
    ../portaly-payment/references/api-contract.md
    Authoritative API contract. Use for callback payload fields, subscription lifecycle endpoints, and the
    subscriptionId === sessionId
    contract.
  • references/health-check-contract.md
    用于获取完整检查项定义、严重程度、通过/失败标准,以及上报API协议。
  • references/common-pitfalls.md
    用于获取真实集成中发现的已知Bug的详细说明,包括错误与正确实现及检测方法。当用户在交互式修复流程中选择
    [?]
    (了解更多)时加载此文件。
  • references/fix-explanations.md
    用于获取所有26项检查的用户可见平实语言文案:平实标题、重要性说明、影响范围、非影响范围。在第一层总结渲染和每个交互式修复流程项中加载。请勿即兴改写——保持总结和逐项视图中的标准表述一致。
  • scripts/report.mjs
    用于完全自动化的CI/CD扫描——执行全部26项检查,打印格式化报告,并将结果POST到portaly.ai。支持
    --fail-on critical
    参数控制CI退出码。
  • scripts/computeHealthScore.mjs
    0–100健康分数公式的标准实现。被
    report.mjs
    导入,并与Vibe仪表板同步,确保技能终端和仪表板始终显示相同分数。
  • scripts/check_signature_sort.mjs
    用于自动化验证项目文件中的签名排序模式。被
    report.mjs
    内部调用。
  • scripts/check_subscription_lifecycle.mjs
    用于自动化追踪订阅ID生命周期。被
    report.mjs
    内部调用。
  • references/ci-setup-guide.md
    当用户想要设置GitHub Actions、预推送钩子或npm脚本进行自动扫描时使用。
  • 交叉参考:
    ../portaly-payment/scripts/sign_callback.mjs
    Portaly回调签名的标准实现。用作正确实现的参考。
  • 交叉参考:
    ../portaly-payment/references/api-contract.md
    权威API协议。用于获取回调负载字段、订阅生命周期端点,以及
    subscriptionId === sessionId
    协议。