The whole laboratory API: lab_api_spec, lab_api_read, lab_api_write #6

Merged
claude merged 4 commits from oss-oo/all-laboratory-features into main 2026-10-27 16:18:11 +00:00
Member

The owner wants the plugin to master every feature of the laboratory; the same is asked of the ChatGPT and Z plugins. The laboratory API has 519 operations (253 writes), and the gateway curates 25 of them. This PR adds three tools that reach all of them as the agent identity:

Tool Does
lab_api_spec Searches the laboratory's API description (cached for a day): method, path, parameters, and whether the plugin allows the call
lab_api_read GETs any path with query parameters; long answers are cut with a note
lab_api_write POST/PUT/PATCH/DELETE with a JSON body (passed on stdin, not argv)

Guard (check_operation in the core). It refuses what is the owner's, whatever the identity's rights; all agent identities are org admins now:

  • administration
  • tokens, OAuth applications, keys, secrets and webhooks
  • deleting repositories or organizations
  • transfers
  • branch protection
  • access grants
  • repository visibility, archival or renames

Paths must be plain API paths: no host, no query, no ...

Checked live on the station: spec release asset finds the asset upload, api GET …/topics reads, and api DELETE /repos/OSS-OO/claude-plugin is refused.

Verification: sh scripts/check.sh passes: 34 Python tests (guard matrix, path rules, method, body and token on the wire, truncation, spec search, stdin body), assets, validate, and 18 of 18 mod tests.

Next, as the owner chose: the same contract as gateway tools in the laboratory, so the ChatGPT and Z plugins get it too.

🤖 Generated with Claude Code

The owner wants the plugin to master **every feature of the laboratory**; the same is asked of the ChatGPT and Z plugins. The laboratory API has 519 operations (253 writes), and the gateway curates 25 of them. This PR adds three tools that reach all of them as the agent identity: | Tool | Does | | --- | --- | | `lab_api_spec` | Searches the laboratory's API description (cached for a day): method, path, parameters, and whether the plugin allows the call | | `lab_api_read` | `GET`s any path with query parameters; long answers are cut with a note | | `lab_api_write` | `POST`/`PUT`/`PATCH`/`DELETE` with a JSON body (passed on stdin, not argv) | **Guard** (`check_operation` in the core). It refuses what is the owner's, whatever the identity's rights; all agent identities are org admins now: - administration - tokens, OAuth applications, keys, secrets and webhooks - deleting repositories or organizations - transfers - branch protection - access grants - repository visibility, archival or renames Paths must be plain API paths: no host, no query, no `..`. **Checked live on the station:** `spec release asset` finds the asset upload, `api GET …/topics` reads, and `api DELETE /repos/OSS-OO/claude-plugin` is refused. **Verification:** `sh scripts/check.sh` passes: 34 Python tests (guard matrix, path rules, method, body and token on the wire, truncation, spec search, stdin body), assets, `validate`, and 18 of 18 mod tests. **Next, as the owner chose:** the same contract as gateway tools in the laboratory, so the ChatGPT and Z plugins get it too. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
claude agent added 1 commit 2026-10-27 15:07:27 +00:00
The whole laboratory API: lab_api_spec, lab_api_read, lab_api_write
Some checks failed
ci / check (pull_request) Has been cancelled
5f151507a3
The owner wants the plugin to master every feature of the laboratory
(also asked of the ChatGPT and Z plugins). The API has 519 operations
(253 writes); the gateway curates 25. Three tools now reach all of them
as the agent identity:

- lab_api_spec searches the laboratory's API description (cached a day)
  and says per operation whether the plugin allows it
- lab_api_read GETs any path with query parameters, cutting long answers
- lab_api_write POSTs, PUTs, PATCHes or DELETEs with a JSON body (on
  stdin, not argv)

The core's check_operation refuses what is the owner's, whatever the
identity's rights: administration, tokens, OAuth applications, keys,
secrets, webhooks, deleting repositories or organizations, transfers,
branch protection, access grants, and repository visibility, archival or
renames. Paths must be plain API paths (no host, query, '..').

Tests: 34 Python (guard matrix, path rules, method/body/token on the
wire, truncation, spec search, stdin body) and 18 mod tests. README,
skill and AGENTS.md describe the tools and the guard. Version 0.3.0.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent referenced this pull request from a commit 2026-10-27 15:11:19 +00:00
claude agent added 1 commit 2026-10-27 15:11:19 +00:00
Writes become an allow-list of project work
All checks were successful
ci / check (pull_request) Successful in 4s
78bbe44bbf
Security review of #6: a deny-list does not keep an org-admin agent from
owner-level operations. Against the laboratory's swagger 173 writes
passed it, among them organization and repository settings, runners and
variables, mirrors and the agent's own account.

check_operation now allows writes only for project work (issues, pull
requests, comments, reviews, labels, milestones, releases and assets,
tags, branches, files, commit statuses, topics, description and website,
avatar and social preview, wiki, workflow dispatch, notifications, agent
work grants, new repositories and forks) and refuses everything else. A
repository PATCH may touch only description and website. Reads stay open
but for credentials (adds runner registration tokens and push mirrors).
Paths are percent-decoded once and checked, deny patterns ignore case,
a second /api/v1 is refused, and the URL is re-quoted from the checked
path. lab_api_spec judges templates with sample values, so it marks
id-carrying operations right. Swagger tally: 217 reads and 63 writes
allowed, 239 refused.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent added 1 commit 2026-10-27 15:51:32 +00:00
Guard edge cases: anchored routes, printable paths, '--' before values
All checks were successful
ci / check (pull_request) Successful in 8s
9feb412ea5
An independent edge-case suite (277 table-driven tests, now in
lab/test_guard_edges.py; 1,044 option variants) found no bypass and seven
behaviours that differed from the intent; each is fixed:

- credential-area patterns matched ordinary names (a file in hooks/, a
  branch named keys); they are anchored to their API routes now
- control characters and lone surrogates passed normalize_path; paths
  and query values must be printable
- model values could be read as CLI options (a path of -h printed the
  help); the mod puts options first, then '--', then method, path,
  target, repository or words; a lone '--' path is refused cleanly
- a query key holding '=' was re-split; the mod sends the query as one
  JSON object (--query-json)
- a trailing newline passed the write patterns; they use fullmatch and
  check_operation refuses unprintable paths
- a deeply nested body crashed the CLI; it is refused instead

Checked live: a file under hooks/ reads, the webhooks route stays
refused, releases read with a JSON query.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent added 1 commit 2026-10-27 16:12:56 +00:00
Close the last guard gaps from the extended edge suite
All checks were successful
ci / check (pull_request) Successful in 9s
7a9d8a4ffd
The edge-case reviewer extended its suite (now 410 tests; 3,324
sub-cases; anchored routes against the laboratory's spec, printable
query values, deep nesting, a mutation check) and found nine small gaps
at the edges of the previous fixes, none a way through the guard:

- the mod passes option values as --tail=, --step= and --method=, so no
  value of the model is read as an option
- a lone '--' as job id or method is refused instead of sent
- --query-json nested too deeply is refused instead of crashing
- non-string query values are sent as JSON (true, null, 3)
- a body that is not JSON (a set, NaN) is refused; bodies are encoded
  with allow_nan=False
- the suite's mirrors and pins follow register.tsx, including all nine
  labci() calls

444 Python tests and 18 mod tests pass.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
claude agent merged commit 6071b0d6c0 into main 2026-10-27 16:18:11 +00:00
claude agent deleted branch oss-oo/all-laboratory-features 2026-10-27 16:18:11 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
OSS-OO/claude-plugin!6
No description provided.