Skip to content

Update demo video to v2 - #16

Merged
sonichi merged 1 commit into
mainfrom
update-demo-v2
Mar 28, 2026
Merged

sonichi merged 1 commit into
mainfrom
update-demo-v2

Conversation

@sonichi

@sonichi sonichi commented Mar 28, 2026

Copy link
Copy Markdown
Owner

New demo video with spell corrections.

New inline video and YouTube link.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@sonichi
sonichi merged commit 7ded5cd into main Mar 28, 2026
@sonichi
sonichi deleted the update-demo-v2 branch March 28, 2026 18:56
liususan091219 added a commit that referenced this pull request Apr 13, 2026
…35-36)

Existing resolve() + is_relative_to() + regex guards in agent-api.py
and dashboard.py properly block all path traversal attempts. CodeQL
flags these as false positives because it can't track taint through
the validation logic. POC: scripts/poc-codeql-path-injection.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
liususan091219 added a commit that referenced this pull request Apr 13, 2026
…28-31, #35-36)

CodeQL couldn't track taint through _safe_id() function calls or
conditional regex match checks. Restructured to use re.sub() inline
before Path() constructors so taint is visibly broken in the same scope.

- agent-api.py: inline re.sub in _safe_path(), /media/, /answer handlers
- dashboard.py: re.sub + reassign slug before Path() in GET and DELETE

No behavior change — same sanitization logic, restructured for static analysis.
Includes POC: scripts/poc-codeql-path-injection.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sonichi pushed a commit that referenced this pull request Apr 14, 2026
* fix: validate display param is numeric (CodeQL #33)

Unsanitized display query param flowed into subprocess.run args.
Add isdigit() check so only numeric values reach screencapture.
Includes POC script: scripts/poc-codeql-33-cmd-injection.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: escape backslashes before quotes in AppleScript strings (CodeQL #42, #39)

The .replace(/"/g, '\\"') only escaped quotes but not backslashes.
A backslash before a quote (\\") would become \\" which closes the
AppleScript string context. Fix: escape backslashes first, then quotes.
Includes POC: scripts/poc-codeql-42-39-string-escaping.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: POC confirms path injection guards work (CodeQL #16-23, #28-31, #35-36)

Existing resolve() + is_relative_to() + regex guards in agent-api.py
and dashboard.py properly block all path traversal attempts. CodeQL
flags these as false positives because it can't track taint through
the validation logic. POC: scripts/poc-codeql-path-injection.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use hostname endswith instead of substring check (CodeQL #38)

"ts.net" in url matches spoofed hostnames like evil-ts.net.attacker.com.
Parse URL and check hostname endswith(".ts.net") instead.
POC: scripts/poc-codeql-38-url-substring.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: reduce phone number exposure in logs (CodeQL #37)

Extract masked phone to separate variable and reduce visible digits
from 6 (2+4) to 4 (2+2). Breaks CodeQL taint flow from env var
to console.log.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sonichi pushed a commit that referenced this pull request Apr 14, 2026
…28-31, #35-36) (#323)

CodeQL couldn't track taint through _safe_id() function calls or
conditional regex match checks. Restructured to use re.sub() inline
before Path() constructors so taint is visibly broken in the same scope.

- agent-api.py: inline re.sub in _safe_path(), /media/, /answer handlers
- dashboard.py: re.sub + reassign slug before Path() in GET and DELETE

No behavior change — same sanitization logic, restructured for static analysis.
Includes POC: scripts/poc-codeql-path-injection.sh

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
sonichi added a commit that referenced this pull request Apr 20, 2026
-23) (#488)

9 open CodeQL path-injection alerts across 3 sites in src/agent-api.py.
All three had strong existing sanitization (regex whitelist +
is_relative_to confinement), but CodeQL doesn't recognize
is_relative_to as a taint sanitizer. Apply the Path.name pattern
matching PR #487's dashboard.py fix:

1. _safe_path(base_dir, filename) — the task/result lookup helper
   (alerts #16-19). Rebuild filename via Path(name + ".txt").name.

2. /media/{rel} handler (alerts #7, #20-21). Multi-segment; split on
   "/" and rebuild each component via Path(p).name, then joinpath.

3. Inline task-file build for "answer-{qid}-{ts}.txt" (alerts #22-23).
   Apply Path(...).name to the full basename.

Path.name is functionally a no-op after the regex whitelist (no
separators possible), but it's a CodeQL-recognized path-injection
sanitizer that breaks the taint flow CodeQL tracks through f-string
path construction. Same pattern Mini validated on #487.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
sonichi added a commit that referenced this pull request May 3, 2026
…579)

Picks up two upstream merges:
- #16 replay-text wait-silently in BOTH reconnect paths (eliminates
  greeting bleed-through after reconnect)
- #17 deadline the reconnect promise to avoid stuck RECONNECTING after
  ECONNRESET-during-reconnect (previously required launchctl kickstart
  to recover; observed 5+ min stuck on 2026-05-01)
sonichi pushed a commit that referenced this pull request May 5, 2026
PR #579 bumped the dependency reference but left the resolved field at
ee58489a, so `npm install` reused the cached older bodhi tarball. Voice
agents started after #579 still loaded the pre-fix code (no silent-replay
instructions on either reconnect path).

Fix: rerun `npm install github:sonichi/bodhi_realtime_agent#ffec0cd` to
update the resolved entry. Now next voice-agent restart actually picks up
bodhi #16 (silent-replay text in both reconnect paths) and #17 (reconnect
promise deadline).

Co-authored-by: Vasiliy Radostev <vasiliyr@Vasiliys-MacBook-Pro.local>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
New inline video and YouTube link.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
liususan091219 added a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…ichi#39, sonichi#42) (sonichi#320)

* fix: validate display param is numeric (CodeQL sonichi#33)

Unsanitized display query param flowed into subprocess.run args.
Add isdigit() check so only numeric values reach screencapture.
Includes POC script: scripts/poc-codeql-33-cmd-injection.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: escape backslashes before quotes in AppleScript strings (CodeQL sonichi#42, sonichi#39)

The .replace(/"/g, '\\"') only escaped quotes but not backslashes.
A backslash before a quote (\\") would become \\" which closes the
AppleScript string context. Fix: escape backslashes first, then quotes.
Includes POC: scripts/poc-codeql-42-39-string-escaping.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* test: POC confirms path injection guards work (CodeQL sonichi#16-23, sonichi#28-31, sonichi#35-36)

Existing resolve() + is_relative_to() + regex guards in agent-api.py
and dashboard.py properly block all path traversal attempts. CodeQL
flags these as false positives because it can't track taint through
the validation logic. POC: scripts/poc-codeql-path-injection.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: use hostname endswith instead of substring check (CodeQL sonichi#38)

"ts.net" in url matches spoofed hostnames like evil-ts.net.attacker.com.
Parse URL and check hostname endswith(".ts.net") instead.
POC: scripts/poc-codeql-38-url-substring.sh

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: reduce phone number exposure in logs (CodeQL sonichi#37)

Extract masked phone to separate variable and reduce visible digits
from 6 (2+4) to 4 (2+2). Breaks CodeQL taint flow from env var
to console.log.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
liususan091219 added a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
-23, sonichi#28-31, sonichi#35-36) (sonichi#323)

CodeQL couldn't track taint through _safe_id() function calls or
conditional regex match checks. Restructured to use re.sub() inline
before Path() constructors so taint is visibly broken in the same scope.

- agent-api.py: inline re.sub in _safe_path(), /media/, /answer handlers
- dashboard.py: re.sub + reassign slug before Path() in GET and DELETE

No behavior change — same sanitization logic, restructured for static analysis.
Includes POC: scripts/poc-codeql-path-injection.sh

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…chi#7, sonichi#16-23) (sonichi#488)

9 open CodeQL path-injection alerts across 3 sites in src/agent-api.py.
All three had strong existing sanitization (regex whitelist +
is_relative_to confinement), but CodeQL doesn't recognize
is_relative_to as a taint sanitizer. Apply the Path.name pattern
matching PR sonichi#487's dashboard.py fix:

1. _safe_path(base_dir, filename) — the task/result lookup helper
   (alerts sonichi#16-19). Rebuild filename via Path(name + ".txt").name.

2. /media/{rel} handler (alerts sonichi#7, sonichi#20-21). Multi-segment; split on
   "/" and rebuild each component via Path(p).name, then joinpath.

3. Inline task-file build for "answer-{qid}-{ts}.txt" (alerts sonichi#22-23).
   Apply Path(...).name to the full basename.

Path.name is functionally a no-op after the regex whitelist (no
separators possible), but it's a CodeQL-recognized path-injection
sanitizer that breaks the taint flow CodeQL tracks through f-string
path construction. Same pattern Mini validated on sonichi#487.

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…onichi#579)

Picks up two upstream merges:
- sonichi#16 replay-text wait-silently in BOTH reconnect paths (eliminates
  greeting bleed-through after reconnect)
- sonichi#17 deadline the reconnect promise to avoid stuck RECONNECTING after
  ECONNRESET-during-reconnect (previously required launchctl kickstart
  to recover; observed 5+ min stuck on 2026-05-01)
liususan091219 pushed a commit to liususan091219/sutando-fork that referenced this pull request May 28, 2026
…#593)

PR sonichi#579 bumped the dependency reference but left the resolved field at
ee58489a, so `npm install` reused the cached older bodhi tarball. Voice
agents started after sonichi#579 still loaded the pre-fix code (no silent-replay
instructions on either reconnect path).

Fix: rerun `npm install github:sonichi/bodhi_realtime_agent#ffec0cd` to
update the resolved entry. Now next voice-agent restart actually picks up
bodhi sonichi#16 (silent-replay text in both reconnect paths) and sonichi#17 (reconnect
promise deadline).

Co-authored-by: Vasiliy Radostev <vasiliyr@Vasiliys-MacBook-Pro.local>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liususan091219 added a commit that referenced this pull request Jun 8, 2026
…ills PR #16)

Piece 3 of multi-bot meeting-mode. Ports name-gate.ts (pure decision logic:
isAddressedBy / decideForTurn with sticky last-addressed semantics) from
sonichi/sutando-skills PR #16 and wires it as the speak-gate:

- Session defaults to meeting-mode (silent) when the gate is active (stand name
  set + >=1 peer name configured via SUTANDO_PEER_NAMES, default Lucy/Maddy/Mini/Pro/Sutando).
- Each user turn runs decideForTurn(gate, text): addressed-to-me -> allow (break
  silence this turn); addressed-to-another -> drop; neither -> sticky carries.
- Gate auto-disables (always allow) when no peer is configured -> single-bot unchanged.
- Local string/regex match, no LLM -> zero added latency.

Pairs with hear-all-voice (SUTANDO_ALLOWED_BOT_USER_IDS at launch) so bots hear
everyone but only speak when named. tsc clean. Remaining: owner-presence.

Co-Authored-By: Claude Opus 4.8 (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.

1 participant