From 37d8739df90b0f7918e784fed84b32743e72079a Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 21 Jun 2026 13:36:37 +0000 Subject: [PATCH] routing: constrain Unauthorized / KMS / mismatch signals (v0.6.8) Finishes the v0.6.7 routing-robustness pass by constraining the last three bare signatures from the v0.6.2 audit. detect_domain only; guarded by routing-corpus (every golden case still top-2) and negative-corpus. - Unauthorized (security): now requires "401 Unauthorized" or an access/request/ operation/credential/signature neighbour (was bare, matched any prose). - KMS (security): now requires the kms: action form or a crypto neighbour (key/encrypt/decrypt/SSE/cipher/CMK/GenerateDataKey) (was bare). - mismatch (data-consistency): now requires a data neighbour (etag/checksum/hash/ md5/content/object/data/digest/size/byte), so "version/schema mismatch" no longer misroutes (was bare). Three negative-corpus cases lock the guards; verified the real forms still fire and dependent golden cases (kms-denied-encrypt, multipart-etag-rechunk-mismatch) still route. Validation: all gates green; 219 pytest + 21 extension tests; 32/32 baselines PASS. Version 0.6.7 -> 0.6.8. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01QhkyBLeDtBTmvTdVBqgCAV --- CHANGELOG.md | 23 +++++++++++++++++++ docs/ARCHITECTURE.md | 2 +- docs/cli-reference.md | 2 +- pyproject.toml | 2 +- skill-registry.yaml | 2 +- storageops_cli/extensions/storageops.ts | 6 ++--- .../extension/routing-negative-corpus.test.ts | 15 ++++++++++++ 7 files changed, 45 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67a27f3..eea56e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,28 @@ # Changelog +## 2026-06-21 — v0.6.8: Routing robustness, continued — constrain the last over-broad signals + +Finishes the routing-robustness pass started in v0.6.7 by constraining the three +remaining bare signatures the v0.6.2 audit flagged. `detect_domain` only, guarded by +routing-corpus (every golden case still recalls its skill top-2) and negative-corpus. + +- **`Unauthorized`** (security): `[/Unauthorized/i]` matched any prose use + ("unauthorized change to the wiki"). Now requires `401 Unauthorized` or an + access/request/operation/credential/signature neighbour. +- **`KMS`** (security): `[/KMS/i]` matched any mention. Now requires the `kms:` action + form or a crypto neighbour (key/encrypt/decrypt/SSE/cipher/CMK/GenerateDataKey), so + an unrelated "KMS team roadmap" no longer routes to security. +- **`mismatch`** (data-consistency): `[/mismatch/i]` matched "version mismatch", + "schema mismatch". Now requires a data neighbour (etag/checksum/hash/md5/content/ + object/data/digest/size/byte), so a "firmware version mismatch" no longer routes to + data-consistency. +- Three negative-corpus cases lock the new guards; verified the real forms still fire + (`401 Unauthorized`, `kms:GenerateDataKey`, `ETag mismatch`) and the dependent + golden cases (`kms-denied-encrypt`, `multipart-etag-rechunk-mismatch`) still route. + +Validation: all gates green; 219 pytest + 21 extension tests (incl. 3 new +negative-corpus cases); 32/32 baselines 100% PASS. Version 0.6.7 → 0.6.8. + ## 2026-06-21 — v0.6.7: Routing robustness Closes the routing gaps flagged in the v0.6.2 audit and deferred since. Changes are diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 3d3e4bb..44f6d6d 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -1,6 +1,6 @@ # Architecture -StorageOps v0.6.7 is a Pi Coding Agent extension and skill pack. +StorageOps v0.6.8 is a Pi Coding Agent extension and skill pack. ## Components diff --git a/docs/cli-reference.md b/docs/cli-reference.md index 77ee9a6..780c3c6 100644 --- a/docs/cli-reference.md +++ b/docs/cli-reference.md @@ -41,7 +41,7 @@ from the older local package. Deployment provenance is written to ## `storageops --version` ```text -StorageOps v0.6.7 (pi: 0.78.0) +StorageOps v0.6.8 (pi: 0.78.0) httpmon : /root/.storageops/bin/httpmon api key : api-key file independent install : yes (~/.storageops/agent) diff --git a/pyproject.toml b/pyproject.toml index 4b7ca4d..9c4339f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "storageops" -version = "0.6.7" +version = "0.6.8" description = "StorageOps — S3-compatible object storage diagnostic toolkit. A Pi Coding Agent extension + skill pack." requires-python = ">=3.11" readme = "README.md" diff --git a/skill-registry.yaml b/skill-registry.yaml index 0e82114..44b7d0a 100644 --- a/skill-registry.yaml +++ b/skill-registry.yaml @@ -1,4 +1,4 @@ -# StorageOps Skill Registry v0.6.7 +# StorageOps Skill Registry v0.6.8 # Machine-readable metadata for all StorageOps skills. # Skills are auto-discovered by Pi from the skills/ directory. diff --git a/storageops_cli/extensions/storageops.ts b/storageops_cli/extensions/storageops.ts index dd37c04..785c54f 100644 --- a/storageops_cli/extensions/storageops.ts +++ b/storageops_cli/extensions/storageops.ts @@ -144,8 +144,8 @@ const DOMAIN_SIGNATURES: Record> = { [/403\s*(?:Forbidden|Access\s*Denied)/i, "access_denied"], [/AccessDenied/i, "access_denied_api"], [/InvalidAccessKeyId/i, "invalid_key"], - [/KMS/i, "kms_error"], - [/Unauthorized/i, "unauthorized"], + [/kms:\w|\bKMS\b.*\b(key|encrypt|decrypt|SSE|cipher|grant|CMK|GenerateDataKey)\b|\b(key|encrypt|decrypt|SSE|cipher|CMK)\b.*\bKMS\b/i, "kms_error"], + [/401\s*Unauthorized|\bUnauthorized\b.*\b(request|access|operation|principal|credential|token|user|role|perform|API|HTTP|header|signature)\b|\b(request|access|operation|principal|credential|token|HTTP|API|signature)\b.*\bUnauthorized\b/i, "unauthorized"], [/AssumeRole|sts:/i, "role_error"], [/权限|无权限|鉴权|拒绝访问|访问被拒/i, "access_denied_cjk"], ], @@ -213,7 +213,7 @@ const DOMAIN_SIGNATURES: Record> = { "storageops-data-consistency": [ [/consistenc|一致性/i, "consistency"], [/stale|陈旧/i, "stale"], - [/mismatch/i, "mismatch"], + [/\bmismatch\b.*\b(etag|checksum|hash|md5|sha|content|object|data|digest|size|byte)\b|\b(etag|checksum|hash|md5|sha|content|object|data|digest)\b.*\bmismatch\b/i, "mismatch"], [/checksum|ETag/i, "checksum"], ], "storageops-bigdata-pipeline": [ diff --git a/tests/extension/routing-negative-corpus.test.ts b/tests/extension/routing-negative-corpus.test.ts index d6c4162..49ec8ed 100644 --- a/tests/extension/routing-negative-corpus.test.ts +++ b/tests/extension/routing-negative-corpus.test.ts @@ -60,6 +60,21 @@ const NEGATIVE_CASES: NegativeCase[] = [ text: "We must keep the service available at all costs during the migration window.", forbidden: [["storageops-lifecycle-cost", "cost"]], }, + { + name: "unauthorized wiki edit is not a security access denial", + text: "An unauthorized change to the internal wiki page was reverted by the editor.", + forbidden: [["storageops-security-iam-policy", "unauthorized"]], + }, + { + name: "firmware version mismatch is not data-consistency", + text: "The release notes flag a firmware version mismatch between the two appliances.", + forbidden: [["storageops-data-consistency", "mismatch"]], + }, + { + name: "bare KMS acronym without crypto context is not a kms error", + text: "The KMS team will present the quarterly knowledge-management-system roadmap.", + forbidden: [["storageops-security-iam-policy", "kms_error"]], + }, ]; test("routing negative corpus blocks known bare-substring false positives", () => {