Skip to content

feat(#179): canonicalize watcher wings at parse boundary (5th + final) - #188

Merged
jphein merged 1 commit into
mainfrom
feat/watcher-parse-boundary-canon
May 29, 2026
Merged

feat(#179): canonicalize watcher wings at parse boundary (5th + final)#188
jphein merged 1 commit into
mainfrom
feat/watcher-parse-boundary-canon

Conversation

@jphein

@jphein jphein commented May 29, 2026

Copy link
Copy Markdown
Collaborator

Fifth and final write surface for #179. The watcher isn't an HTTP endpoint so the pydantic-body approach doesn't apply directly — but the same architectural goal does: canonicalize at the input boundary so all downstream code can trust the WatchTarget.

Pre-#179: parse_watch_dirs ran normalize_wing_name only on path-derived wings; explicit path=Wing_Name env entries flowed through verbatim and were normalized later in _internal_mine at use-time.

Post-#179: parse_watch_dirs normalizes both branches. WatchTargets always carry canonical slugs. The use-time normalize in _internal_mine drops to a comment explaining the new invariant.

Test added: Palace_Daemon and palace_daemon env entries produce identical WatchTarget.wing values. This was the shape of the pre-#175/#178 bug class.

This closes the wing-canonicalization migration that began with #172. All 11 wing/room-accepting sites in palace-daemon now canonicalize at the input boundary:

Surface Mechanism PR
GET /search, /list, /search/fast FastAPI Depends() #180
POST /search/keyword, /search/hybrid, /search/age-fused pydantic #181
POST /backfill-age pydantic #182
POST /silent-save pydantic #183
POST /mine pydantic #184
POST /memory pydantic #186 / #187
PALACE_WATCH_DIRS watcher.parse_watch_dirs this PR

Fifth and final write surface for #179. The watcher isn't an HTTP
endpoint so it can't take a pydantic body — but the same architectural
goal applies: canonicalize wing at the *input* boundary so all
downstream code can trust the WatchTarget is canonical.

Pre-#179: parse_watch_dirs ran ``normalize_wing_name`` only on
path-derived wings (when env entry was bare ``path`` with no
``=wing``). Explicit ``path=Wing_Name`` env entries were passed through
verbatim, and a defensive ``_normalize_wing_slug`` ran later in
_internal_mine before subprocess spawn.

Post-#179: parse_watch_dirs normalizes both branches (path-derived AND
explicit) through normalize_wing_name. WatchTargets always carry
canonical slugs. The use-time normalize in _internal_mine drops to a
comment explaining the new invariant.

Test added: ``Palace_Daemon`` and ``palace_daemon`` env entries
produce identical WatchTarget.wing values ("palace_daemon"). Was the
shape of the pre-#175/#178 bug class — mixed-case writes paired with
canonical reads producing empty result sets.

This closes the wing-canonicalization migration that began with #172.
All 11 wing/room-accepting sites in palace-daemon now canonicalize at
the input boundary:

Read side (#180):
  GET /search, GET /list, GET /search/fast — FastAPI Depends()
Write body (#181, #182, #183, #184, #186, #187):
  POST /search/keyword, POST /search/hybrid, POST /search/age-fused,
  POST /backfill-age, POST /silent-save, POST /mine, POST /memory —
  pydantic body models in search_models.py
Internal env (this PR):
  PALACE_WATCH_DIRS via watcher.parse_watch_dirs

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings May 29, 2026 01:50
@gemini-code-assist

Copy link
Copy Markdown

Warning

You have reached your daily quota limit. Please wait up to 24 hours and I will start processing your requests again!

@jphein
jphein merged commit 44b3c5e into main May 29, 2026
1 check failed
@jphein
jphein deleted the feat/watcher-parse-boundary-canon branch May 29, 2026 01:51

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

jphein added a commit that referenced this pull request May 29, 2026
…s incident

#179 closed — wing/room canonicalization now structural across all 11
surfaces (#180#188). Documents the #187 validate_default regression and
the #185 stale-deploy incident (dead Syncthing on familiar let deploy.sh
restart on stale source while reporting success).

Reorders open work: #185 promoted to "actionable, unblocked" as the
smallest next item.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants