fix(server): wrap the shared client-name alternation like claudewatcher does (#209) #214
Open
mathias
wants to merge 2 commits from
wt/client-pattern into main
pull from: wt/client-pattern
merge into: :main
:main
:wt/client-pattern
:wt/legacy-move
:wt/web-clip
:wt/watcher-write-safety
:wt/wing-layout
:wt/inbox-zero
:fix/pipeline-writes-158
:fix/edit-path-io-192
:fix/create-regular-188
:fix/guard-special-179
:fix/linkcheck-keeps-write-178
:fix/write-dir-redirect-173
:fix/tunnel-detect-174
:fix/pipeline-root-157
:w3/154-mcp-auth-wiring
:fix/tunnel-traversal
:test/in-brain-targets-171
:fix/brain-scan-root-157
:fix/graph-wiki-root-157
:fix/vectorstore-root-157
:fix/notes-root-157
:fix/search-root-157
:fix/brainwide-root-157
:fix/raw-symlinks-153
:feat/symlink-tripwire-157
:fix/rest-auth-149
:fix/123-brain-edit-envelope-check
:feat/106-page-aware-extraction
:fix/105-source-drift-on-main
:fix/104-surface-merge-conflicts-on-main
:agent/b1-compile-on-ingest
:agent/104-surface-merge-conflicts
:agent/105-source-drift
:agent/107-loud-unconfigured-alerting
:feat/brain-read-edit
:fix/capture-i1-refusal-names-target
:renovate/configure
:feat/consolidate-single-harness
:icebox/cmd-routing
:feat/brain-pending-promote
:fix/close-session-classification-refresh
:fix/capture-summarywriter
No Reviewers
Labels
Clear labels
agent/ready
blocked/client
blocked/supplier
blocked/upstream
risk/high
risk/low
risk/medium
size/l
size/m
size/s
size/xs
status:dispatch
status:dispatched
status:review
status:reviewing
type/chore
type/decision
type/docs
type/feat
type/fix
type/ops
type/research
type/test
Meets the agent-ready contract; authorizes unattended execution
Waiting on the client
Waiting on a supplier
Waiting on an upstream project or vendor
Irreversible, security-relevant, or control plane
Reversible, local, test-covered
Touches shared state, deploys or data
Too big - split it
Under two days
Under half a day
Under an hour
Maintenance, no behaviour change
Human decision required; never agent/ready
Documentation only
New capability
Corrects broken behaviour
Infrastructure, deploy, runtime
Investigate; output is a finding, not code
Test coverage only
No labels
Milestone
No items
No Milestone
Projects
Clear projects
No projects
No Assignees
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: mathias/hyperguild#214
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Sprint #209, PR-D (small). Risk: medium by label (part of the client-content filter). Routing is still OFF in production.
Found while preparing the infra change that turns routing on: the deployment injects
CLAUDE_INGEST_CLIENT_BLOCK(SOPS/ExternalSecretclaude-ingest-client-block) as a bare alternation of client names, andclaudewatchercompiles it as(?i)\b(<names>)\b(cmd/server/main.go, claudewatcher scrubber). The router introduced in #211 used it raw as its fallback pattern, so a short client name would match inside ordinary words (difin "different", "modifying") and park clips that have nothing to do with the client — fail-closed, but it would swampneeds-review/the day routing is enabled.Change
ingestClientPattern(getenv):INGEST_CLIENT_BLOCKis a complete regexp, used as is; otherwiseCLAUDE_INGEST_CLIENT_BLOCKis wrapped\b(...)\b. The router's own case-insensitivity and Unicode folding still apply on top.Evidence
Tests first, red then green; mutation-checked (unwrapped fallback fails both tests): a short client name does not park "a different approach to modifying prompts", and does park "kickoff for the DIF project" and "Trucker, the client, asked for".
go vet,go test -race ./...exit 0, 0 FAIL, lint 0.Not covered
The folding views (whitespace removed) interact with
\b: the collapsed view keeps word boundaries, the whitespace-free view does not, so\bname\bis evaluated mainly against the as-is and collapsed views. Stated in docs/raw-inbox.md limits.🤖 Generated with Claude Code
Created via git-mcp on behalf of @mathias
- WrapNames bounds the bare name list with Unicode-aware edges instead of \b (Go's \b is ASCII-only, so a name with a non-ASCII edge letter such as Åke, Société, Ørsted would never have matched), and validates the list on its own: it must compile, must not match the empty string, and cannot break out of its group ('x)|.*(' compiles alone only if balanced) - NewRouter refuses any pattern that matches text naming no client - docs state the whole-word semantics and what is not matched Mutation-checked. Open decision for Mathias: whole-word versus substring recall for a confidentiality filter (plurals, CamelCase and digits glued on do not match). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>Independent review pass 1 (pr-gatekeeper agent, by execution): BLOCK. Resolution at
80f3fd3(tests first, mutation-checked):\bis ASCII-only, so a name likeÅke,Société,Ørsted,Zoëhad no boundary against a space and was never parked (the unwrapped code had matched them by substring: a regression I introduced; claudewatcher's\b(...)\bhas the same hole, inherited). Replaced with Unicode-aware edges:(?:^|[^\p{L}\p{N}])(?:names)(?:[^\p{L}\p{N}]|$). Tests with Å/é/Ø names.x)|.*(-> every note parked;acme)|(b).WrapNamesvalidates the list ON ITS OWN first (must compile, must not match "", so it cannot break out of the group). Startup error otherwise.a||b,acme|,|acme) parked everything with no signal. Refused at startup;NewRouteralso refuses any full pattern that matches "" or "x".)breakout, bad patterns, precedence ofINGEST_CLIENT_BLOCK. Import grouping fixed.\b). Stated in the docs.Not changed, needs Mathias's decision: whole-word versus substring recall for a confidentiality filter. As it stands plurals (
truckers), CamelCase (AcmeCorp) and digits glued on (acme2) pass;trucker_ecommerce,Trucker's, fullwidth, Cyrillic lookalikes, zero-width splits andt r u c k e rare parked. Wider (substring) recall catches more but would also park a short name inside ordinary words (difin "different"). I do not know the real names, so I cannot size either error. Also noted: the whitespace-free view makes word edges mean punctuation only, so single-letter fragments split by spaces (co-a bforab) can park an unrelated note; the upside is thatd i fis caught.Gate:
go vet ./...,go test -race ./...exit 0, 0 FAIL, lint 0.Created via git-mcp on behalf of @mathias
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.