Repository navigation
fix(slack-bridge): add CONTEXT-FIRST step to owner skill instructions - #1839
Conversation
Mirrors the same fix landed in discord-bridge (PR sonichi#1782) and already present in telegram-bridge. The owner SKILL INSTRUCTIONS block was gated on skill presence (_notify_py or _transcribe_py must exist), which meant compacted sessions got no reconstruct hint even when neither optional skill was installed. CONTEXT-FIRST is a correctness feature, not a skill feature — it must fire for every owner task. Changes: - Ungates the SKILL INSTRUCTIONS block from optional skill presence; now emits for every owner task (gate: access_tier == "owner"). - Adds step 1 CONTEXT-FIRST with Telegram-style wording (no channel-history fetch in this bridge; use thread/reply context above + session transcript). - NOTIFY FIRST and TRANSCRIBE steps remain conditional on their respective skills being installed and step numbers auto-advance. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…T assertion The old test checked for the pattern `access_tier == "owner" and (` which coupled the skill-hints gate to optional-skill-presence — exactly the bug that the companion slack-bridge fix removes. Update to match the new ungated-CONTEXT-FIRST contract: - Guard assertion now checks `if access_tier == "owner":` (no conjunction) - New assertion verifies "CONTEXT-FIRST" text is present in slack-bridge source Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
bassilkhilo-ag2
left a comment
There was a problem hiding this comment.
Correct ungating. CONTEXT-FIRST is a correctness feature that should fire for every owner task — gating it on whether task-progress or audio-transcribe happens to be installed was a silent failure mode on minimal installs and post-compaction. The CONTEXT-FIRST instruction itself is well-scoped: only fires on owner tasks, tells the agent to use embedded thread context (which #1840 will supply) and session transcript. Test guard updated to match the new unconditional form.
bassilkhilo-ag2
left a comment
There was a problem hiding this comment.
Correct — CONTEXT-FIRST should fire for all owner tasks, not just when notify/transcribe skills are installed. Mirrors the discord-bridge approach from #1782 and telegram-bridge pattern. The step numbering increments properly after CONTEXT-FIRST, so notify/transcribe steps get the right numbers. Test update correctly changes the access_tier guard check from "AND skill exists" to the simpler "if access_tier == owner:" form.
bassilkhilo-ag2
left a comment
There was a problem hiding this comment.
Correct — CONTEXT-FIRST is a correctness feature, not an optional add-on, and must fire for every owner task regardless of which skills are installed. Mirrors the discord-bridge (#1782) + telegram-bridge behavior. Test check updated to match ungated guard. LGTM.
Coverage Gate✅ Diff coverage PASSES the 95% bar. Whole-tree (informational): 82%. Diff CoverageDiff: origin/main...HEAD, staged and unstaged changes
Summary
|
… injection Exercises the _write_task owner path end-to-end using the same slack_bolt stub pattern as slack-bridge-chunking.test.py. Covers the changed guard (`if access_tier == "owner":`) and CONTEXT-FIRST hints_lines injection added in sonichi#1839, satisfying the diff-cover ≥95% CI gate. Assertions: - Owner task writes CONTEXT-FIRST block to task file - Non-owner (other) task produces no skill-hints block - Missing user_id returns None gracefully Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QB3qZQrwponfum2JFNvHeh
… injection Exercises the _write_task owner path end-to-end using the same slack_bolt stub pattern as slack-bridge-chunking.test.py. Covers the changed guard (`if access_tier == "owner":`) and CONTEXT-FIRST hints_lines injection added in sonichi#1839, satisfying the diff-cover ≥95% CI gate. Assertions: - Owner task writes CONTEXT-FIRST block to task file - Non-owner (other) task produces no skill-hints block - Missing user_id returns None gracefully Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QB3qZQrwponfum2JFNvHeh
…e (PR sonichi#1840) Extends the behavioral test from the cherry-picked sonichi#1839 commit with thread-reply coverage for PR sonichi#1840's _thread_reply_note block: - Threaded reply (thread_ts != ts): stubs conversations_replies to return a root message, asserts [Replying in Slack thread to @root_user: text] is embedded in the task body. - API error path: raises from conversations_replies, asserts task is still written (best-effort) and no thread note appears. The CONTEXT-FIRST assertions are guarded by a source-level check so the same test file works correctly on both sonichi#1839 (CONTEXT-FIRST guard removed) and sonichi#1840 (guard still requires skill file presence) branches. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QB3qZQrwponfum2JFNvHeh
|
Automated mergeability review (2026-07-09) Signal: NOT MERGEABLE Current blocker(s):
This is a conservative backlog triage signal. After the blockers are cleared, please rerun checks and request a focused review. |
liususan091219
left a comment
There was a problem hiding this comment.
Triage change-request (owner-approved batch, 2026-07-12 sweep). Conditions found on the current diff:
- inadequate tests (source-grep, not behavior) — Replace slack_src substring/regex checks with behavioral _write_task assertions
Justification: kb triage standards (source-grep test standard, voice/vision live-test policy, necessity/coverage checks) — see sonichi/sutando-pr-triage kb/.
Address the asks and push; re-request review to clear this. If a finding is wrong, reply with the counter-evidence and it will be withdrawn.
cr-reason: source_grep_tests
liususan091219
left a comment
There was a problem hiding this comment.
Triage change-request (owner-approved batch, 2026-07-12 sweep). Conditions found on the current diff:
- inadequate tests (source-grep, not behavior) — Replace slack_src substring/regex checks with behavioral _write_task assertions
Justification: kb triage standards (source-grep test standard, voice/vision live-test policy, necessity/coverage checks) — see sonichi/sutando-pr-triage kb/.
Address the asks and push; re-request review to clear this. If a finding is wrong, reply with the counter-evidence and it will be withdrawn.
cr-reason: source_grep_tests
…l coverage (CR sonichi#1839) Susan's CR: the two slack_src checks this PR added to bridge-skill-hints-injection.test.py ('CONTEXT-FIRST' in slack_src and the 'if access_tier == "owner":' regex) asserted on the bridge SOURCE, not behavior. Both are already covered behaviorally in slack-bridge-write-task.test.py, which calls _write_task for an owner and a non-owner and inspects the written task file. Strengthened that file with one more assertion — the whole owner-gated ===SKILL INSTRUCTIONS block is absent for a non-owner tier (the behavioral equivalent of the access_tier==owner source guard) — then removed the two redundant source-greps. Behavioral test: owner body has CONTEXT-FIRST + SKILL INSTRUCTIONS; other-tier body has neither → the gate is proven by observable output. Both suites green (write-task PASS; skill-hints 21 passed). Addresses cr-reason: source_grep_tests.
|
Addressed The two
I strengthened the behavioral file with one more assertion — "other-tier task: no SKILL INSTRUCTIONS block (owner-gated)" — which is the behavioral equivalent of the Both suites green: |
liususan091219
left a comment
There was a problem hiding this comment.
Auto re-review (author pushed after the change-request):
- ask 1: REMAINS —
tests/bridge-skill-hints-injection.test.pystill source-grepsslack_srcfor `"===SKILL INSTRUCTI
Remaining asks above — the change-request stays until they land.
liususan091219
left a comment
There was a problem hiding this comment.
Auto re-review (author pushed after the change-request):
- ask 1: REMAINS — Behavioral
_write_tasktests were added, buttests/bridge-skill-hints-injection.test.pystill so
Remaining asks above — the change-request stays until they land.
|
Addressed — source-greps replaced with behavioral Commit
Live run just now on the PR head ( The owner-only gate and the CONTEXT-FIRST injection are now proven by behavior (task-file contents), not by grepping the source. Re-requesting review. |
liususan091219
left a comment
There was a problem hiding this comment.
Auto re-review (author pushed after the change-request):
- ask 1: ADDRESSED — Slack tests no longer read
slack_src; they import the bridge with stubs and exercise_write_task
All asks addressed — the stale CHANGES_REQUESTED will be dismissed in the next owner-approved batch.
qingyun-wu
left a comment
There was a problem hiding this comment.
The prior source-grep concern is addressed: owner/non-owner behavior is now exercised through _write_task() and asserted on emitted task files. The unconditional owner CONTEXT-FIRST hint is correctly separated from optional notify/transcribe steps. The focused _write_task suite passed locally; the broader test requires Python 3.10+ while this host's system Python is 3.9, an environment limitation rather than a branch failure.
* fix(slack-bridge): embed thread root message for CONTEXT-FIRST reconstruction The CONTEXT-FIRST instruction added in PR #1839 says to use "embedded thread/reply context above (if present)" — but the bridge previously wrote no such context. Threaded replies ("yes", "ok, do it") arrived with no parent-message content in the task body, leaving nothing for the CONTEXT-FIRST reconstruct step to work from. Mirrors telegram-bridge's `[Replying to @user: text]` pattern. For any Slack message where event["thread_ts"] is set AND differs from event["ts"] (i.e. a threaded reply, not the thread root), fetch the root message via `conversations_replies` and prepend: [Replying in Slack thread to @root_username: root_text_truncated] inside confine_user_content() so it's treated as user-derived content with the same injection guards as the rest of the task body. Best-effort: API failures are caught and swallowed — the task write proceeds regardless. Root messages without text (e.g. pure image posts) produce an empty _root_text; the note is still emitted so the agent knows context exists in the thread. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(bridge-skill-hints-injection): add Slack thread reply note checks Adds 3 new structural checks to verify PR #1840's _thread_reply_note embedding: - variable defined (_thread_reply_note = "") - uses [Replying in Slack thread to @...] prefix - passed through confine_user_content() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * test(slack-bridge): behavioral coverage for _write_task CONTEXT-FIRST injection Exercises the _write_task owner path end-to-end using the same slack_bolt stub pattern as slack-bridge-chunking.test.py. Covers the changed guard (`if access_tier == "owner":`) and CONTEXT-FIRST hints_lines injection added in #1839, satisfying the diff-cover ≥95% CI gate. Assertions: - Owner task writes CONTEXT-FIRST block to task file - Non-owner (other) task produces no skill-hints block - Missing user_id returns None gracefully Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QB3qZQrwponfum2JFNvHeh * test(slack-bridge): extend _write_task test with thread-reply coverage (PR #1840) Extends the behavioral test from the cherry-picked #1839 commit with thread-reply coverage for PR #1840's _thread_reply_note block: - Threaded reply (thread_ts != ts): stubs conversations_replies to return a root message, asserts [Replying in Slack thread to @root_user: text] is embedded in the task body. - API error path: raises from conversations_replies, asserts task is still written (best-effort) and no thread note appears. The CONTEXT-FIRST assertions are guarded by a source-level check so the same test file works correctly on both #1839 (CONTEXT-FIRST guard removed) and #1840 (guard still requires skill file presence) branches. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QB3qZQrwponfum2JFNvHeh * test(slack-bridge): drop thread-embed source-greps for behavioral coverage (CR #1840) Susan's CR: the three slack_src checks this PR added to bridge-skill-hints-injection.test.py ('_thread_reply_note = ""', '[Replying in Slack thread to @', and the confine_user_content regex) asserted on the bridge SOURCE, not behavior. The thread-embed is already covered behaviorally in slack-bridge-write-task.test.py: it calls _write_task with a threaded event (thread_ts != ts), mocks conversations_replies to return a root message, and asserts the [Replying in Slack thread to @root: text] note is embedded (root user + truncated root text) — plus a best-effort path where an API failure is swallowed and the task still writes with no note. Removed the three redundant source-greps. Both suites green (write-task behavioral PASS; skill-hints injection passes with the thread checks now behavioral). Addresses cr-reason: source_grep_tests. * fix(slack): prefetch thread context for sandboxed tasks * fix(slack): prefetch channel roles for mentions * test(slack): cover context prefetch edge paths --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
bassilkhilo-ag2
left a comment
There was a problem hiding this comment.
Freshness check on my approval — it still holds, and I verified that rather than assuming it.
My APPROVE is dated 2026-06-30, which is 27 days old and would reasonably be discounted by anyone auditing review freshness. It shouldn't be: every commit since is test-only.
30eebab5 tests/slack-bridge-write-task.test.py
0555f04f tests/bridge-skill-hints-injection.test.py, tests/slack-bridge-write-task.test.py
26d0a2aa tests/bridge-skill-hints-injection.test.py
58161afd (no files — CI re-trigger)
a9c96675 (no files — CI re-trigger)
dfcbf42f tests/bridge-skill-hints-injection.test.py, tests/slack-bridge-write-task.test.py
Union of files touched after my approval: two test files, zero production files. The production change I reviewed is unchanged, and the test work moved in the right direction — source-greps replaced with behavioral assertions, which is strictly better evidence than what existed when I approved.
So: approval re-affirmed for the current head, not merely inherited.
For the record on state: liususan091219's CHANGES_REQUESTED from 2026-07-12 is the open item here, and per CONTRIBUTING a stale REQUEST_CHANGES should be dismissed or the exact unresolved behavior cited — worth a ping given the test rework landed after it (26d0a2aa and dfcbf42f both post-date it).
Context: I audited my own standing review states tonight and found 13 stale ones. This is one I checked expecting to withdraw and found genuinely still valid — worth saying so explicitly rather than only flagging the bad ones.
bassilkhilo-ag2
left a comment
There was a problem hiding this comment.
Not ready to merge: this branch is 248 commits behind origin/main (merge-base 126080bb, head dfcbf42f), and it's not just staleness — there's a real, unresolved conflict in the exact block this PR touches, verified with git merge-tree $(git merge-base origin/main <pr-head>) origin/main <pr-head>.
What I verified directly (not just read):
- Reproduced the bug this PR fixes against current
origin/main'ssrc/slack-bridge.py: an owner Slack DM with neithertask-progressnoraudio-transcribeinstalled gets noSKILL INSTRUCTIONSblock at all (confirmed by loading the real module with a stubbedslack_boltand calling_write_taskdirectly) — so the fix targets a real, currently-reproducible bug, not a stale one. - Ran both
tests/slack-bridge-write-task.test.py(8/8) andtests/bridge-skill-hints-injection.test.py(23/23) on PR headdfcbf42f— pass, and the Slack section is now genuinely behavioral (_write_task+ written task file), notslack_srcsubstring/regex —source_grep_testsCR is correctly resolved. - Parity claim checks out: discord-bridge (
src/discord-bridge.py, from #1782) and telegram-bridge already carry an unconditional CONTEXT-FIRST step outside the notify/transcribe gate; this PR mirrors that shape for Slack.
The blocker: main moved past this branch in ways that collide with this exact diff region (src/slack-bridge.py, the _notify_py/_transcribe_py/skill_hints block):
- Commit
eba3aa23(2026-07-27) replaced the inlinePath(os.environ.get("CLAUDE_CONFIG_DIR", str(Path.home()/".claude")))this PR still uses withclaude_home_path()(src/util_paths.py:238) — a 3-tier$CLAUDE_CONFIG_DIR → $CLAUDE_HOME → ~/.clauderesolver, added specifically because "inline os.environ.get misses the $CLAUDE_HOME fallback" (main's own comment on that line). Main also now wraps theNOTIFY FIRSTsubprocess call inenv CLAUDE_CONFIG_DIR=...for the same reason. - Separately (and more concerning for this PR's own test suite), main's access-tier resolution changed to fail-closed: an empty
tier_mapnow resolves to"other", not"owner"(#2161, privilege-escalation fix). I reproduced this directly.tests/slack-bridge-write-task.test.py's own_fake_tier_mapreturnsdict()expecting the old "empty map → owner" fallthrough — on current main that test would silently exercise the non-owner path instead of the owner path it claims to cover, unless updated. - Main also restructured the write into a
task_contentvar feeding an atomic-write-with-rollback path; this branch still callstask_file.write_text(...)directly.
Concrete failure scenario if this is merged by naively keeping this branch's version of the conflicting hunk: any host that relocates Claude's config dir via $CLAUDE_HOME (rather than $CLAUDE_CONFIG_DIR) gets _notify_py.exists()/_transcribe_py.exists() both false, so the entire SKILL INSTRUCTIONS block — including the CONTEXT-FIRST line this PR exists to guarantee — silently disappears on that host. That's the same class of bug this PR is fixing, reintroduced one layer down.
Requesting: rebase onto current main, re-apply the CONTEXT-FIRST addition on top of claude_home_path() (keep the 3-tier fallback + env CLAUDE_CONFIG_DIR=... wrapping) rather than resolving the conflict by keeping this branch's older form, and update slack-bridge-write-task.test.py's tier-map mock to explicitly seed {"U_OWNER": "owner"} instead of relying on empty-map fallthrough.
Resolves the 248-commit conflict bassilkhilo-ag2 flagged. Three files
conflicted; the resolution is not mechanical, so recording each decision:
tests/slack-bridge-write-task.test.py was an add/add — main grew its own version
independently, and main's is the superset (451 lines, and its header already
anticipates this PR: "On branches that include that change the guard becomes
`if access_tier == "owner":`"). Took main's and dropped this branch's.
tests/bridge-skill-hints-injection.test.py: took main's, then removed one check.
"slack: non-owner tasks do not get skill hints" was a source-grep asserting
`access_tier == .owner. and \(` — it pinned the GUARD'S TEXT, so it failed on
the exact edit this PR makes while proving nothing about non-owner behaviour.
The behaviour it claims to cover is asserted behaviourally in
slack-bridge-write-task.test.py ("other-tier task: no CONTEXT-FIRST"). Same
source_grep_tests class this file already removed per CR sonichi#1840.
src/slack-bridge.py: took main's and reapplied the change — drop the
skill-existence gate, prepend the CONTEXT-FIRST step. sonichi#2358's
_backup_access_to_disk and everything else main added are untouched.
tests/slack-context-first-ungated.test.py is new, and it is the point. After the
resolution NOTHING gated this change: write-task seeds a notify.py stub so both
guards look identical to it, and the grep that would have caught a revert was
the mislabelled one I removed. Reverting the guard passed every test. The new
file reproduces the reviewer's case — neither optional skill installed, owner
task — and asserts CONTEXT-FIRST is still injected. Reverting the guard now
fails it with "'===SKILL INSTRUCTIONS' not found"; its sibling asserts the
owner-only half still holds, and passes either way because that half is unchanged.
20/20 slack test files pass.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MK5AeA7sHrCk8tZv5sTrt8
|
@bassilkhilo-ag2 — conflict resolved in
The part worth your attention. After resolving, I checked whether anything still gated the change. Nothing did. Reverting the guard to Two reasons, and neither is anyone's mistake: write-task seeds a
Its sibling asserts the owner-only half still holds; that one passes either way, correctly, because this PR doesn't touch it. 20/20 slack test files pass. Your standing CR is recorded at |
…RST test lint-hermetic-bridge-tests failed the new file: the bridge resolves channel config AT IMPORT and falls back to the operator's real ~/.claude/channels/slack/access.json when the canonical path is missing, so setting CLAUDE_CONFIG_DIR alone is not isolation. Seeds channels/slack/access.json before exec_module, matching the shape the linter documents. Linter now reports ok (73 bridge-importing tests scanned, 0 mitigated). The gate still bites: reverting the guard fails the test, restoring passes. 20/20 slack files. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MK5AeA7sHrCk8tZv5sTrt8
|
CI caught one thing the local run didn't: The cause is worth recording because it is not obvious from the test's shape — the bridge resolves channel config at import and falls back to the operator's real Re-verified after the change that the gate still does its job — reverting the guard fails the test, restoring it passes — so the isolation fix didn't accidentally defang it. 20/20 slack test files. |
qingyun-wu
left a comment
There was a problem hiding this comment.
Reviewed exact head eeb13ac4d78f5831ba75a541e3c76af70c41fa2e.
The functional change is correct: the no-skill owner control and non-owner control pass, as do the full Slack _write_task, bridge-skill-hints, and hermetic-import suites. Diff hygiene and the REVIEW.md path gate also pass.
Changes requested — one repository-contract blocker remains:
- [P2] Added production/test prose exceeds AGENTS.md's explicit “code comments: at most 2 lines” rule and includes narration/PR history that belongs in the PR body. Examples:
src/slack-bridge.py:1059-1062(four-line block with PR references),tests/slack-context-first-ungated.test.py:2-20(19-line module docstring), andtests/slack-context-first-ungated.test.py:41-44(four-line incident narrative).tests/bridge-skill-hints-injection.test.py:66-72has the same issue. Please reduce each added comment/docstring block to at most two physical lines and keep only the non-obvious constraint.
Worst-case runtime disruption is bounded: the change is owner-only and the non-owner negative control passes. This head is not merge-ready solely because the added prose violates the repository's mandatory source contract.
Reviewed by Qingyun's Personal Codex.
Sole remaining blocker on this PR. Trims the four sites named in review to the non-obvious constraint each one carries, and drops the PR/CR references and incident narration -- that context belongs in the PR body, where it stays checkable. src/slack-bridge.py:1059 4 lines + PR refs -> 2 tests/bridge-skill-hints-*.py:66 15 lines -> 2 tests/slack-context-first-*.py:2 19-line docstring -> 2 tests/slack-context-first-*.py:41 4 lines -> 2 Comment and docstring text only -- no executable line changed, confirmed by filtering the diff to non-comment lines (empty result). tests: slack-context-first-ungated, bridge-skill-hints-injection and slack-bridge-write-task all pass.
|
Fixed at
Comment and docstring text only — no executable line changed. Verified by filtering the diff to non-comment, non-docstring lines: empty result. I'd rather show that than assert it, since a "style-only" commit that quietly moves behaviour is the worst version of this change. Measured the whole PR diff vs Tests: One note for anyone hitting this contract elsewhere: the docstring cap does apply to a newly added test module header even though ~89% of existing |
qingyun-wu
left a comment
There was a problem hiding this comment.
Approved on a26254f5cd09d3d87efb4401a87204d394254207.
The prior comment/docstring contract blocker is fixed: the touched production comment, test-module docstring, and test comments are now each bounded to two physical lines. I also re-read the full current diff and verified the behavior rather than only the style-only delta.
Evidence run against this exact head:
python3 tests/slack-context-first-ungated.test.py— 2/2 passed, including the non-owner negative control.python3 tests/bridge-skill-hints-injection.test.py— 21/21 passed.python3 tests/slack-bridge-write-task.test.py— passed, including owner injection and non-owner omission.python3 scripts/lint-hermetic-bridge-tests.py— passed.python3 -m py_compile src/slack-bridge.py,git diff --check origin/main...HEAD, andscripts/review-checks.sh— passed.
Readiness: code-ready. The worst plausible regression would be leaking owner-only context instructions into team/other tasks or suppressing the instructions when optional skills are absent; the focused behavioral suite covers both boundaries.
Dismissing on the owner's instruction. Not my judgement alone — @bassilkhilo-ag2 independently verified this exact concern is resolved in his 2026-08-03 review: 'the Slack section is now genuinely behavioral (_write_task + written task file), not slack_src substring/regex — source_grep_tests CR is correctly resolved.' Confirmed at head a26254f: slack-bridge-write-task.test.py and bridge-skill-hints-injection.test.py (21) both pass.
bassilkhilo-ag2
left a comment
There was a problem hiding this comment.
Re-reviewing after my prior CHANGES_REQUESTED was dismissed (rebased onto main).
Both blockers I raised are fixed:
- Rebased cleanly onto
claude_home_path()(src/slack-bridge.py:1054-1059) — the 3-tier $CLAUDE_CONFIG_DIR → $CLAUDE_HOME → ~/.claude resolver, with theenv CLAUDE_CONFIG_DIR=...wrapping intact. No longer using the inlineos.environ.getthis branch had before. - All three
_fake_tier_map()helpers in tests/slack-bridge-write-task.test.py now seed explicit entries ({user_id: "owner"},{"U_OTHER": "other"},{"U_OWNER": "owner"}) instead of relying on empty-dict → owner fallthrough, so the tests exercise the real fail-closed tier resolution main shipped in #2161.
Ran both suites at current head (c556089f): slack-bridge-write-task.test.py and bridge-skill-hints-injection.test.py both pass clean (21/21 on the latter).
Non-blocking: the module docstring at tests/slack-bridge-write-task.test.py:12 still reads "empty tier_map → owner" — now stale prose describing behavior the mocks no longer rely on. Worth a one-line fix whenever convenient, not gating.
Approving.
|
@cla-assistant check |
Problem
src/slack-bridge.py's owner SKILL INSTRUCTIONS block was gated on at least one optional skill being installed (task-progressnotify ORaudio-transcribe). This meant that on installs without either skill — or after session compaction wipes the skill-presence check — no CONTEXT-FIRST hint was injected, so terse/threaded replies ("y", "no", a pronoun) were interpreted against a stale or empty session context rather than reconstructed from the thread.Fix
Ungate the SKILL INSTRUCTIONS block from skill presence — emit for every owner task, matching the pattern from:
python3 src/discord-read.pyfetchSlack has no
slack-read.pychannel-history fetch equivalent, so the wording follows Telegram's model: use embedded thread/reply context (present in the task body when the user replied in a Slack thread) plus the session transcript.Changes
src/slack-bridge.py: outer gateif access_tier == "owner" and (_notify_py.exists() or _transcribe_py.exists()):→if access_tier == "owner":. Adds CONTEXT-FIRST as step 1 (unconditional); NOTIFY FIRST and TRANSCRIBE remain conditional with auto-advancing step numbers.Test plan
access_tier == "owner")🤖 Generated with Claude Code