chore: promote runtime surface deriv@1.0.2 - #9
Conversation
Built by scripts/build-promotion-bundle.mjs from scripts/promotion-allowlist.json in the private working repo, at master 04174e7. Copy-by-inclusion: 116 allowlisted paths plus the 4 public-repo scaffold files, 27 modified, none added or removed. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.OpenSSF Scorecard
Scanned Manifest Files.github/workflows/publish.yml |
ako-deriv
left a comment
There was a problem hiding this comment.
Reviewed the workflow hardening, the verifier changes, the manifests, and the skill/docs overlays. Everything checks out; CI is green on the current verify-surface.mjs, .mcp.json matches the new URL pin, and the ws-demo/ws-real overlay fix is correct — I re-fetched the live developers.deriv.com/llms/ws-demo.md and its example really does send {"ws_demo":1} on the public socket, which contradicts its own otp query-param schema, so replacing that with "connect to the OTP URL" is the right call.
Good fixes worth calling out:
source_repo_namenow derives from the trustedvars.PROMOTION_SOURCE_REPOinstead of the dispatch payload.- The surface guard now runs from the checked-out
.github/workflows/verify-surface.mjs, not from inside the artifact it is checking. git add -Abeforegit diff --cached --quietcloses the untracked-new-file blind spot in the "nothing to commit" branch.- The
create-github-app-tokenSHA3ff1caaa…is the actualv2.0.2tag; the previousd72941d…pin was mislabeled. Might be worth a one-liner in the PR body since the description calls the workflow changes out but not this.
One trust-model note, not a blocker: with the cp _staged/.github/workflows/publish.yml step, the promoter can now rewrite the receiver's own workflow (the App needs Workflows: write for exactly this, as the comment says). That's a deliberate and documented extension of the existing trust boundary — the artifact must come from the validated source repo's release — so fine, just flagging it for anyone reading the history.
Everything else is nits, inline. Approving.
Pre-existing nit outside the diff: publish.yml step 6 comment still says "13 allowlisted runtime paths"; the allowlist is 116 now.
| --exclude '.git' --exclude '.github' \ | ||
| --exclude '_staged' --exclude '_incoming' \ | ||
| _staged/ ./ | ||
| cp _staged/.github/workflows/publish.yml .github/workflows/publish.yml |
There was a problem hiding this comment.
Nit / question: only publish.yml is synced from _staged/.github/, but verify-surface.mjs, verify-surface.yml, and update-changelog.mjs (which this workflow depends on) are not — this PR carries a verify-surface.mjs change by hand that the steady-state receiver wouldn't pick up. If "the artifact must never replace its own verifier in the same run" is the intent, a short comment here would make that explicit. Either way, a [ -f _staged/.github/workflows/publish.yml ] || fail "artifact is missing publish.yml" guard would give a legible error instead of a bare cp failure under set -e.
| deletes=$(rsync -a --delete --dry-run --itemize-changes \ | ||
| --exclude '.git' --exclude '.github' \ | ||
| --exclude '_staged' --exclude '_incoming' \ | ||
| _staged/ ./ | grep -F '*deleting' || true) |
There was a problem hiding this comment.
Nit: under pipefail, the trailing || true also swallows an rsync failure in the dry-run, not just grep's no-match exit. Harmless in practice since the real rsync below would then fail under set -e, but if you want the guard to be strict you could check PIPESTATUS[0] or run the dry-run to a file first.
| ``` | ||
|
|
||
| ```javascript | ||
| onUserConfirmed(() => ws.send(JSON.stringify({ buy: pendingProposal.id, price: pendingProposal.ask_price }))); |
There was a problem hiding this comment.
Nit (docs pseudo-code): if the user confirms before a proposal message arrives, pendingProposal is undefined and this throws. A one-line guard (if (!pendingProposal) return;) keeps the snippet copy-paste safe, and it's also a natural place to note that proposal ids expire and should be refreshed rather than reused.
| ``` | ||
|
|
||
| ```javascript | ||
| onUserConfirmed(() => ws.send(JSON.stringify({ buy: pendingProposal.id, price: pendingProposal.ask_price }))); |
There was a problem hiding this comment.
Same nit as in examples.md: guard against pendingProposal being undefined when the confirmation fires early.
| does not collect API tokens. It asks you to configure nothing. There are | ||
| no user Deriv credentials in this plugin. | ||
| The hosted server's own deployment secrets are never part of the plugin; | ||
| deployment secrets are not in this repo. |
There was a problem hiding this comment.
Nit: these two sentences say the same thing ("deployment secrets are never part of the plugin" / "deployment secrets are not in this repo"). One of them can go.
Promotes the plugin runtime surface to
deriv@1.0.2.Built by
scripts/build-promotion-bundle.mjsfromscripts/promotion-allowlist.jsonin the private working repo atmaster04174e7. Copy-by-inclusion — 27 files modified, none added, none removed; 116 allowlisted paths plus the 4 public-repo scaffold files, 120 total.What this carries
1.0.1→1.0.2across all four manifests. Version-only in.claude-plugin/,.cursor-plugin/and.codex-plugin/— no other field moved.deriv-market-data,deriv-trade-lifecycleandderiv-trade-typesreturn to"Live Deriv API guides, schemas, examples, and payload validation"— the copy authored here in docs: align marketplace listing copy with Deriv UX writing #7, which the1.0.1promotion overwrote with the upstream wording. That decision is now settled upstream at the authoring root (deriv-com/deriv-api-mcp8f2d892), so it will not be reverted again by a later refresh.deriv-authkeeps its authentication wording and both chart skills keep their chart-feed wording; docs: align marketplace listing copy with Deriv UX writing #7 never touched those. A gate in the working repo now fails a later tidy-up that flattens them all.publish.ymlno longer evaluates atarlisting through a pipeline wherepipefailplus SIGPIPE could invert the traversal guard;verify-surface.mjsgains presence, MCP URL pin and Codex gates.README.mdandSECURITY.md.deriv-llmssnapshot date moves with no content change — the published pages re-fetched byte-identical, so the date records when the snapshot was last verified.Verification
Run against this branch's tree before pushing:
verify-surface.mjsas it exists onmastertoday (what CI runs on this PR):OK — 120 path(s), surface + content + internal-reference gates cleanverify-surface.mjsas this PR replaces it:OK — 120 path(s), surface + presence + MCP URL pin + content + internal-reference + Codex gates cleanskills/*/SKILL.mdfrontmatter blocks parse — 0 failures.mcp.jsonpinshttps://mcp-api-v2.deriv.com/mcp; Codexinterface.developerNamestays lowercasederivmasterwas exactly 27 modified, 0 untracked, 0 deleted — matching the measured delta with no surprisesUpstream sync was confirmed before building:
deriv-com/deriv-api-mcpmasteris8f2d892, exactly the commit the working repo's bundle records, and re-running the refresh produced no content change. This repo has had no hand-authored commits since the1.0.1promotion.🤖 Generated with Claude Code