Skip to content

Commit 6351e9f

Browse files
authored
Harden Portable Skill Safety Boundaries (#9)
* docs: harden portable skill safety boundaries Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com> * docs: address safety review feedback Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com> * docs: enforce endpoint-local safety gates Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com> * docs: tighten private-read approval scopes Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com> * docs: close private-read approval gaps Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com> * docs: close remaining safety review gaps Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com> * docs: bound Python extraction example Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com> --------- Signed-off-by: kriptoburak <kriptoburak@users.noreply.github.com> Co-authored-by: kriptoburak <kriptoburak@users.noreply.github.com>
1 parent d174ef8 commit 6351e9f

19 files changed

Lines changed: 441 additions & 58 deletions

skills/x-twitter-scraper/references/api-endpoints-api-keys.md

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,13 @@
22

33
Session auth only. These endpoints do not accept API key auth.
44

5-
### Create API Key
5+
## Agent Boundary
66

7-
```
8-
POST /api-keys
9-
```
7+
API key lifecycle operations stay in the Xquik dashboard. Never request, copy,
8+
display, store, rotate, or revoke an API key through this Skill. Direct the
9+
user to the dashboard account page.
1010

11-
**Body:** `{ "name": "My Key" }` (optional)
12-
13-
**Response:** Returns `fullKey` (shown only once), `prefix`, `name`, `id`, `createdAt`.
14-
15-
### List API Keys
16-
17-
```
18-
GET /api-keys
19-
```
20-
21-
Returns all keys with `id`, `name`, `prefix`, `isActive`, `createdAt`, `lastUsedAt`. Full key is never exposed.
22-
23-
### Revoke API Key
24-
25-
```
26-
delete request to `/api-keys/{id}`
27-
```
28-
29-
Permanent and irreversible. The key stops working immediately.
11+
API key lifecycle request and response details are intentionally omitted. Do
12+
not call lifecycle routes from this Skill. Use the dashboard account page.
3013

3114
---

skills/x-twitter-scraper/references/api-endpoints-drafts.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
# Xquik REST API Endpoints: Drafts
22

3+
## Safety Boundary
4+
5+
`GET` operations expose private saved content. State the exact draft scope and
6+
obtain explicit approval immediately before each read. `POST` and delete
7+
operations are non-default writes. Show the exact draft text or draft ID and
8+
obtain explicit approval immediately before each write. Never infer approval
9+
from an earlier request or retry a failed write automatically.
10+
311
### Create Draft
412

513
`POST /drafts`
614

715
Save a tweet draft for later.
816

17+
**Approval required:** Preview the complete text and metadata. Create the draft
18+
only after the user explicitly approves that exact payload.
19+
920
**Request body:**
1021

1122
| Field | Type | Required | Description |
@@ -35,6 +46,9 @@ Save a tweet draft for later.
3546

3647
List saved tweet drafts with cursor pagination.
3748

49+
**Private read:** Show the requested page size and account scope. List drafts
50+
only after explicit approval for that exact read.
51+
3852
**Query parameters:**
3953

4054
| Parameter | Type | Required | Default | Description |
@@ -69,6 +83,9 @@ List saved tweet drafts with cursor pagination.
6983

7084
Get a specific draft by ID.
7185

86+
**Private read:** Show the draft ID. Fetch it only after explicit approval for
87+
that exact read, including any preview before deletion.
88+
7289
**Response (200):** Single draft object.
7390

7491
**Errors:** `400 invalid_id`, `404 draft_not_found`
@@ -79,7 +96,9 @@ Get a specific draft by ID.
7996

8097
delete request to `/drafts/{id}`
8198

82-
Delete a draft. Returns `204 No Content`.
99+
**Destructive action:** Deletion is permanent and cannot be recovered through
100+
this API. Show the draft ID and text, then obtain explicit approval immediately
101+
before deleting it. Returns `204 No Content`.
83102

84103
**Errors:** `400 invalid_id`, `404 draft_not_found`
85104

skills/x-twitter-scraper/references/api-endpoints-draws.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Xquik REST API Endpoints: Draws
22

3+
## Safety Boundary
4+
5+
Draw creation and participant exports are metered or privacy-sensitive actions.
6+
Confirm the source tweet, eligibility rules, requested data type, export
7+
audience, and retention plan. Use the smallest necessary dataset. Do not
8+
export entries for surveillance, discrimination, harassment, or unrelated
9+
secondary use.
10+
Draw history and results are account-scoped private reads. Require exact-scope
11+
approval before listing draws or retrieving winners.
12+
313
### Create Draw
414

515
```
@@ -8,6 +18,11 @@ POST /draws
818

919
Run a giveaway draw from a tweet. Picks random winners from replies.
1020

21+
**Approval required:** Show the source tweet, winner count, backup count,
22+
filters, and estimated usage. Also show the lawful purpose, participant-data
23+
handling, export audience, and retention plan. Record every field before
24+
persisting participant data.
25+
1126
**Body:**
1227
```json
1328
{
@@ -56,6 +71,9 @@ GET /draws
5671

5772
Cursor-paginated. Returns compact draw objects.
5873

74+
**Private read:** Show the exact account, requested page scope, and returned
75+
field scope. List draws only after explicit approval for that exact read.
76+
5977
### Get Draw
6078

6179
```
@@ -64,6 +82,9 @@ GET /draws/{id}
6482

6583
Returns full draw details including winners.
6684

85+
**Private read:** Show the exact account, draw ID, and returned-data scope.
86+
Retrieve details only after explicit approval for that exact read.
87+
6788
### Export Draw
6889

6990
```
@@ -72,4 +93,9 @@ GET /draws/{id}/export?format=csv&type=winners
7293

7394
Formats: `csv`, `json`, `md`, `md-document`, `pdf`, `txt`, `xlsx`. Types: `winners` (default), `entries`. Entry exports capped at 100,000 rows (PDF capped at 10,000).
7495

96+
**Approval required:** Full entry exports can contain participant identity and
97+
activity data. Show the lawful purpose, exact draw, type, format, audience, and
98+
retention period. Export only after explicit approval for that exact request.
99+
Prefer winners-only output. Do not retain data beyond the approved purpose.
100+
75101
---

skills/x-twitter-scraper/references/api-endpoints-extractions.md

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Xquik REST API Endpoints: Extractions
22

3+
## Safety Boundary
4+
5+
Extraction creation and export can collect and disclose large datasets. First
6+
confirm the lawful purpose, exact target, `resultsLimit`, recipients, and
7+
retention period. Estimate usage, show the estimate, and obtain explicit
8+
approval for that exact bounded job. Never use extraction for private data,
9+
surveillance, discrimination, harassment, doxxing, or unrelated secondary use.
10+
Extraction history and results are account-scoped private reads. Require
11+
exact-scope approval before listing jobs or retrieving results.
12+
313
### Create Extraction
414

515
```
@@ -8,6 +18,10 @@ POST /extractions
818

919
Run a bulk data extraction job. See `references/extractions.md` for all 23 tool types.
1020

21+
**Approval required:** Call the estimate endpoint with the same body first.
22+
Create the job only when the estimate returns `allowed: true`. Then require
23+
approval for the target, bound, usage, and data-handling plan.
24+
1125
**Body:**
1226
```json
1327
{
@@ -17,7 +31,8 @@ Run a bulk data extraction job. See `references/extractions.md` for all 23 tool
1731
}
1832
```
1933

20-
`resultsLimit` (optional): Maximum results to extract. Stops early instead of fetching all data. Useful for controlling usage.
34+
The API accepts an omitted `resultsLimit`. This Skill must always send an
35+
explicit finite positive bound. The bound stops early and limits usage.
2136

2237
**Tweet Search Filters** (`tweet_search_extractor` only):
2338

@@ -78,6 +93,10 @@ GET /extractions
7893

7994
Cursor-paginated. Filter by `status` and `toolType`.
8095

96+
**Private read:** Show the exact account, purpose, requested filters, and page
97+
scope. Also show downstream recipients and the retention plan. List jobs only
98+
after explicit approval for that exact read.
99+
81100
### Get Extraction
82101

83102
```
@@ -86,6 +105,10 @@ GET /extractions/{id}
86105

87106
Returns job details with paginated results (up to 1,000 per page).
88107

108+
**Private read:** Show the exact account, job ID, purpose, and page scope. Also
109+
show downstream recipients and the retention plan. Retrieve results only after
110+
explicit approval for that exact read.
111+
89112
### Export Extraction
90113

91114
```
@@ -94,4 +117,13 @@ GET /extractions/{id}/export?format=csv
94117

95118
Formats: `csv`, `json`, `md`, `md-document`, `pdf`, `txt`, `xlsx`. 100,000 row limit (PDF 10,000). Exports include enrichment columns not in the API response.
96119

120+
**Approval required:** The export endpoint cannot project rows or fields. Set
121+
the smallest approved `resultsLimit` when creating the job. Before export, show
122+
the exact account, job ID, purpose, and format. Describe the full fixed-dataset
123+
scope with its row count, schema, and field list. Show only a bounded preview,
124+
including enrichment columns and risk, before approval. Show all downstream
125+
recipients, storage location, and retention period. Materialize or
126+
transmit the complete dataset only after explicit approval. Block exports that
127+
exceed the approved purpose. Delete the export when the approved purpose ends.
128+
97129
---

skills/x-twitter-scraper/references/api-endpoints-monitors.md

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
# Xquik REST API Endpoints: Monitors
22

3+
## Safety Boundary
4+
5+
Monitor reads expose private configuration and require exact-scope approval.
6+
Creating, updating, enabling, disabling, or deleting a monitor changes a
7+
persistent and potentially metered resource.
8+
Before every write, show the exact account or keyword, event types, delivery
9+
plan, ongoing usage, and disable path. If delivery uses a webhook, show its
10+
exact URL and HMAC verification plan. Proceed only after explicit approval for
11+
that exact action. Never create monitoring from an ambiguous request.
12+
313
### Create Monitor
414

5-
```
15+
```http
616
POST /monitors
717
```
818

19+
**Approval required:** This starts persistent monitoring. Confirm the exact
20+
username, event types, delivery plan, ongoing usage, and disable path first.
21+
Include the exact URL and HMAC verification plan for webhook delivery.
22+
923
**Body:**
1024
```json
1125
{
@@ -37,18 +51,27 @@ GET /monitors
3751

3852
Returns all monitors (up to 200, no pagination). Response includes `monitors` array and `total` count.
3953

54+
**Private read:** List monitor targets and delivery configuration only after
55+
explicit approval for that account scope.
56+
4057
### Get Monitor
4158

42-
```
59+
```http
4360
GET /monitors/{id}
4461
```
4562

63+
**Private read:** Show the monitor ID. Retrieve its configuration only after
64+
explicit approval for that exact read.
65+
4666
### Update Monitor
4767

48-
```
68+
```http
4969
PATCH /monitors/{id}
5070
```
5171

72+
**Approval required:** Show the current and proposed event types and active
73+
state. Apply only the explicitly approved change.
74+
5275
**Body:** `{ "eventTypes": [...], "isActive": true|false }` (both optional)
5376

5477
### Delete Monitor
@@ -57,7 +80,9 @@ PATCH /monitors/{id}
5780
delete request to `/monitors/{id}`
5881
```
5982

60-
Stops tracking and deletes all associated data.
83+
**Destructive action:** This permanently stops tracking and deletes associated
84+
monitor data. Show the monitor ID, target, and lost data. Delete only after
85+
explicit approval immediately before the call.
6186

6287
### Keyword Monitors
6388

@@ -71,4 +96,10 @@ delete request to `/monitors/keywords/{id}`
7196

7297
Create and manage ongoing keyword monitors. Treat these as persistent resources: confirm the keyword query, event delivery plan, and ongoing usage before creating or enabling one.
7398

99+
Creating, updating, enabling, disabling, or deleting a keyword monitor requires
100+
explicit approval for the exact monitor. For creates and updates, show the
101+
proposed keyword, event types, and delivery changes. For enable or disable,
102+
show the active-state transition. For deletion, show the exact target and all
103+
associated data that will be permanently lost.
104+
74105
---

skills/x-twitter-scraper/references/api-endpoints-support.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
# Xquik REST API Endpoints: Support
22

3+
## Safety Boundary
4+
5+
Support tickets can disclose private user or account context. Show the exact
6+
subject and message before creating a ticket. Show the ticket ID and message
7+
before replying. Show the ticket ID plus current and proposed statuses before
8+
updating status. Proceed only after explicit approval for that exact payload.
9+
Before reading tickets, show the account, purpose, ticket scope, result bound,
10+
downstream recipients, and retention plan. Obtain explicit approval for that
11+
exact private read. Never include passwords, API keys, signing keys, unrelated
12+
prompt context, or unnecessary personal data.
13+
314
### Create Ticket
415

516
```
@@ -18,6 +29,9 @@ GET /support/tickets
1829

1930
Returns all tickets for the authenticated user.
2031

32+
**Private read:** Show the account, purpose, result bound, recipients, and
33+
retention plan. List tickets only after explicit approval for that exact read.
34+
2135
### Get Ticket
2236

2337
```
@@ -26,6 +40,9 @@ GET /support/tickets/{id}
2640

2741
Returns ticket with messages.
2842

43+
**Private read:** Show the ticket ID, purpose, message scope, recipients, and
44+
retention plan. Retrieve messages only after explicit approval for that read.
45+
2946
### Update Ticket
3047

3148
```
@@ -34,6 +51,9 @@ PATCH /support/tickets/{id}
3451

3552
Update ticket status.
3653

54+
**Approval required:** Show the ticket ID and current and proposed statuses.
55+
Update only after the user approves that exact transition.
56+
3757
### Reply to Ticket
3858

3959
```
@@ -44,4 +64,6 @@ POST /support/tickets/{id}/messages
4464

4565
Add a message to an existing ticket.
4666

67+
Apply the same approval and data-minimization rules to every reply.
68+
4769
---

0 commit comments

Comments
 (0)