synology: full read-surface sweep + FileStation ls graceful fallback

Exercised every Web API + SSH read command live against cascadesDS.
- All reads OK; `ls <folder>` (FileStation list) is 407-denied for the admin
  account on this box (confirmed on-box as SYSTEM_ADMIN) -> now catches the
  400/407 and prints an SSH file-browse hint. `ls` share-roots still works.
- SSH backend (info/df/run + privileged synowebapi) verified.
- Documented MSYS path-mangling of bare `ls /path` arg on Windows.
- SKILL.md: per-command results; flagged write/setter path as not-yet-live.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-25 11:19:04 -07:00
parent 7173f4dc12
commit fc36f98450
3 changed files with 86 additions and 13 deletions

View File

@@ -110,19 +110,35 @@ log via `.claude/scripts/log-skill-error.sh` before surfacing. Handled condition
VPN-down connect error surfaced to the user, a method refused for lack of --confirm) are NOT logged.
## Status / verification
- **[VERIFIED 2026-06-25 — HOWARD-HOME, Cascades VPN up]** First live exercise against the device.
Confirmed working: auth (sid + synotoken CSRF), API discovery (`apis`), version-by-maxVersion
routing, and reads `test` / `storage` / `shares` / `packages` / `services` / `apis`. Device is
**DS718+, DSM 7.2.1-69057 Update 11, 6 GB RAM, serial 1920PEN537202**; ext4, 2x WD10EZEX 1 TB.
10 shares (incl. hidden `pacs`, `Activities`, `chat`, `Sandra Fish`); 30 packages running incl.
**Active Backup for Business 3.1.0, Synology Drive Server 3.5.0, Chat, VPN Server, Hybrid Share**.
Session-expiry re-login (106/119), the mutating-verb gate, and the generic-error map are coded to
spec but not yet exercised against a live write (no mutating call made yet — gate verified only by
the read path). Built originally from a 5-agent scan of the DSM 7 help tree + authoritative API
sources (kwent `_full.json`, N4S4/synology-api, Synology Web API guides) — see `references/dsm-api.md`.
- **[VERIFIED 2026-06-25 — HOWARD-HOME, Cascades VPN up]** Full read-surface exercise against the
device. Device is **DS718+, DSM 7.2.1-69057 Update 11, 6 GB RAM, serial 1920PEN537202**; ext4,
2x WD10EZEX 1 TB (volume1 913G, 43% used). 10 shares (incl. hidden `pacs`, `Activities`, `chat`,
`Sandra Fish`); 30 packages running incl. **Active Backup for Business 3.1.0, Synology Drive
Server 3.5.0, Chat, VPN Server, Hybrid Share**. 41 users, 4 groups (administrators, http,
MainOffice, users).
- **Command-by-command results (Web API):** `test` `apis` `sysinfo` `util` `storage` `shares`
`users` `groups` `packages` `services` `connections` `ls` (share roots) `call`**all OK**.
Auth (sid + synotoken CSRF), API discovery, version-by-maxVersion routing, and the generic `call`
power-tool all confirmed live.
- **SSH backend (`syno-ssh.sh`):** `info` `df` `run` confirmed OK (incl. privileged `sudo -S` and
on-box `synowebapi --exec` at `/usr/syno/bin/synowebapi`). This is the path for real file browsing.
- **`ls <folder>` (FileStation `list`) is DENIED for the admin account on this box** — returns 407
on-box (SYSTEM_ADMIN) / 400 via Web API even for valid subfolders; the built-in admin lacks
FileStation file privileges. `ls` (no path / share roots via `list_share`) works fine. For actual
file/folder browsing use the SSH backend: `syno-ssh.sh run "ls -la /volume1/<share>/<subpath>"
--confirm`. (`ls <folder>` now catches this and prints the SSH hint.) Windows note: a bare
`ls /Public` arg is also rewritten by MSYS path-conversion — prefer `MSYS_NO_PATHCONV=1` or the
`call ... folder_path=/x` form, but the 407 denial blocks it regardless.
- **WRITE/SETTER PATH NOT YET EXERCISED LIVE.** Session-expiry re-login (106/119), the mutating-verb
gate, and read-modify-write setters are coded to spec but no mutating call has been made against
the device yet. Gate is verified only on the read path. First real change will confirm CSRF on a
write end-to-end.
- Built originally from a 5-agent scan of the DSM 7 help tree + authoritative API sources (kwent
`_full.json`, N4S4/synology-api, Synology Web API guides) — see `references/dsm-api.md`.
- **Live fixes from this run (2026-06-25):** `services` used `SYNO.Core.Service.list` which 103s on
DSM 7.2.1 — corrected to `get` (returns `{"service":[...]}`). `apis | head` raised a
`BrokenPipeError` traceback — now caught and exits cleanly.
`BrokenPipeError` traceback — now caught and exits cleanly. `ls <folder>` now degrades to an SSH
hint on the FileStation 400/407 denial.
- **DSM 7.2.x reboot/shutdown 103:** the Web-API `reboot`/`shutdown` can return error 103 on some
builds. Fallback is the SSH `reboot|shutdown --confirm` recipe (`synoshutdown -r|-s`).
- **Param-schema caveat:** method names + versions in the reference are device-authoritative, but many

View File

@@ -338,8 +338,21 @@ def main(argv):
_print(c.call("SYNO.Core.CurrentConnection", "list"))
elif args.cmd == "ls":
if args.path:
_print(c.call("SYNO.FileStation.List", "list", folder_path=args.path,
additional='["size","owner","time","perm"]'))
try:
_print(c.call("SYNO.FileStation.List", "list", folder_path=args.path,
additional='["size","owner","time","perm"]'))
except SynoError as e:
# FileStation file-browsing (`list`) is denied for an account without
# FileStation file privileges -- on-box it is 407, surfaced here as 400.
# `list_share` (share roots) still works; for actual files use the SSH backend.
if " 400" in str(e) or " 407" in str(e):
raise SynoError(
f"{e}\n [HINT] FileStation file-listing is not permitted for this "
f"account (built-in admin lacks FileStation file privileges on this "
f"device). Use the SSH backend for real file browsing:\n"
f" bash .claude/skills/synology/scripts/syno-ssh.sh run "
f"\"ls -la /volume1/<share>/<subpath>\" --confirm")
raise
else:
_print(c.call("SYNO.FileStation.List", "list_share",
additional='["size","owner","perm"]'))

View File

@@ -17,6 +17,50 @@ Categories (the `[type]` tag): _(none)_ = skill/command execution failure ·
<!-- Append entries below this line -->
2026-06-25 | Howard-Home | synology/ls | [friction] ls <path> arg mangled by MSYS path-conversion (/Public -> C:/Program Files/Git/Public) before Python sees it; FileStation list also 407-denied for admin anyway. Fix: use call folder_path=/x (= form not converted) or MSYS_NO_PATHCONV=1; real file browsing via SSH backend. [ctx: ref=feedback_tmp_path_windows os=windows]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology/ssh | syno-ssh recipe 'run' failed (rc=2) [ctx: host=192.168.0.120]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 401) [ctx: err={"code": 401}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.CheckExist.check failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.CheckExist.check failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.FileStation.List.list failed (code 400) [ctx: err={"code": 400}]
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.list failed (code 103) [ctx: err={"code": 103}]
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.query failed (code 103) [ctx: err={"code": 103}]
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.get_service failed (code 103) [ctx: err={"code": 103}]
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.list_service failed (code 103) [ctx: err={"code": 103}]
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.enum failed (code 103) [ctx: err={"code": 103}]
2026-06-25 | Howard-Home | synology | SYNO.Core.Service.list failed (code 103) [ctx: err={"code": 103}]
2026-06-25 | Howard-Home | bash/reachability-probe | [friction] /dev/tcp TCP probe falsely reported host DOWN on Windows MSYS while device was UP; wasted a cycle. Fix: don't trust /dev/tcp on Git-bash Windows for reachability — use the actual client (python urllib) or curl --max-time.
2026-06-25 | Howard-Home | synology | SYNO.Core.QuickConnect.get failed (code 103) [ctx: err={"code": 103}]