Repository navigation
DO NOT MERGE — merge train: 3261,3181,3227,3252 - #3266
Closed
trinity-ability wants to merge 22 commits into
Closed
trinity-ability wants to merge 22 commits into
trinity-ability wants to merge 22 commits into
Conversation
Dismiss (Abilityai/trinity-enterprise#748): one click ends a pending question or approval as disposition=dismissed (status stays cancelled) through the ask ending sink — audit, thin broadcast, and the filer's wake with its own framing. 5s client-side Undo window; nothing is sent until it lapses. Addressee only (person gate, uniform 404); a dismiss that loses a race, or lands past the deadline, is a no-op. Discuss (Abilityai/trinity-enterprise#747): opens one chat per ask with the asking agent (CAS link in a new platform-only context key), titled after the ask, with the ask as its tile; a turn-context provider puts the ask (id, kind, live status, options) in every turn there. The ask stays one pending row; a question can be answered from the composer with "Send as answer" (written as response). Also renders agent markdown in the ask context's "Your recent answers" list, the surface #3115 missed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Inbox turned Discuss's open-thread into a bare /workspace/c/<id> push, and the #3140 guard read the just-created chat (not yet in the thread list) as not the viewer's. Route it through the shell's openThread, which adopts the id, and refresh the list. The chat tile now forwards open-thread too — its Discuss did nothing before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#747) An answer that woke an opted-in agent left the woken run's output in the execution history only — the person saw the agent start and never saw what it did. The resume run now carries the Workspace destination (the ask's discussion chat, else its attached chat; only when the answerer is the addressee), so the ent#457 completion report posts the result there as an agent message. The open chat watches for it for up to 5 minutes, since it has no history poll. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-discuss-dismiss # Conflicts: # src/frontend/src/components/portal/PortalConversation.vue
…rite errors F1: an answered ask's resume run reports into the ask's DISCUSSION chat only. The attached-chat fallback (Main for a background ask) widened every answered ask's audience to the client — verbatim final reply, shared files, inherited by delegated children. The run is now told its reply goes to the person. Store watch narrowed to match. Tests pin turn_audience and delegation inheritance for the stamped run. F2: the discussion-link write tolerates only SQLite's busy snapshot (OperationalError). Any other failure, or a busy write with no racing link while the ask is still pending, is a retryable 503 instead of "409 This ask is already pending". F3: the discussion's system notice no longer quotes the agent-written title. F4: options are truncated before JSON encoding, keeping the closing quote. F5: Dismiss refuses alerts (422), like Discuss and the card. F7: real TestClient tests through get_portal_principal (agent key 403) and the live in-process limiter (429). Send as answer stands down while a reply chip or attachment is in the composer (#3168 collision). tables.py disposition comment lists dismissed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
operating-room.md: an answered ask's result returns to its discussion chat only; the attached chat is not a destination (F1), so an undiscussed answer's run stays owner-only. backend.md: turn_context now has one OSS provider, the discussed-ask line. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A queued /task row carries delivery settings in backlog_metadata. The push drain applied them in run_async_task; the pull sink wrote the terminal and stopped. On a pull pilot a Chat-tab /task (save_to_session, trigger manual) succeeded and never reached the chat session, and the collaboration activity stayed started. - run_post_turn_delivery: the three post-turn steps (chat-session save and broadcast, collaboration activity, self-task finalisation), moved out of run_async_task. The push drain and the pull sink both call it. - request_from_metadata: the queued-request rebuild, shared by _spawn_drain and the pull sink. - Pull sink: on the CAS-won branch, spawns delivery when the metadata asks for it, then signals the sync waiter with the chat session id; signals at once when there is nothing to deliver. Delivery failure never blocks the signal. - A token-gated SUCCESS write refuses a row already SUCCESS or SKIPPED. The claim token survives the terminal write, so a worker's retried result POST won the CAS twice and would have saved the chat turn twice. A late SUCCESS still corrects a FAILED row. - close_execution_activity and the bulk close also close the collaboration / self-task activity a queued row names, so a terminal written outside run_async_task (pull sink, lease-reaper park, expire, watchdog) does not leave it started. - Sync /task keeps the chat_session_id the sink signals. Fixes #2329 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…pplied terminal (#2329) - The lease reaper closes the dead attempt as CANCELLED on a row it has just re-queued. The queued-activity close now runs only for a row that is terminal, so the collaboration / self-task activity stays open for the re-delivered attempt (a CANCELLED close is never upgraded). - Sink delivery runs only when the row still holds the status its own CAS wrote, so FAILED then a late SUCCESS under one token saves the turn once. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…patch.dict re-import test_channel_image_vision re-imports adapters.message_router inside a patch.dict(sys.modules, ...) that mocks adapters.base. patch.dict puts the original module back in sys.modules on exit, but not the `adapters` package attribute the re-import rebound, and `import adapters.message_router as mr` resolves through that attribute. A later test then received the module built on the mocked ChannelResponse: test_ent751_gate_callers:: test_a_channel_message_held_by_the_gate_is_answered_in_the_conversation failed after test_1533 + test_channel_image_vision, reproduced on the base commit 09f9d08 (pre-existing, order-dependent; surfaced by an -n auto run). An autouse fixture in the polluting file puts the binding back after every test. The three-file reproduction goes from 1 failed to 88 passed. Learnings fragment added (the 2026-08-10 package-attribute / sys.modules class). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…n was approved for it (Abilityai/trinity-enterprise#752) The dispatch-time gate (#751) reads what a requester typed, so a request that names a gated skill only in prose ("please pay the invoice") reached the executor, and the agent's own Skill call loaded the skill. On Claude Code agents a PreToolUse hook now asks the platform before a skill loads into a run, and refuses it unless that run was cleared for it. - Hook: docker/base-image/hooks/skill-gate.py (bootstrap) + _skill_gate.py, registered by its own managed-settings drop-in (/etc/claude-code/managed-settings.d/50-skill-gate.json, root 0444, exec form under `env -i` + `-I -S`, LD_* pinned empty) on Skill and on Agent/Task subagent `skills:` preloads. Identity from /proc (the claude process's launch env, the container's), never its own env. Every outcome is exit 0 or 2 under a 10 s deadline — for this CLI exit 1, a crash or a hook timeout lets the tool run. No verdict → a root-owned marker decides: an agent with gates fails closed, every other agent keeps its skills. - Check: POST /api/skill-gate/check (routers/skill_gate.py), the agent from its key (get_self_agent), every verdict a 200; refusals hand the request back ("…with a message that includes /pay-invoice…"), name no person or role, and are audited skill_gate_refused (throttled). - Clearance is execution + skill (D3), not an input hash: #751's approved-run record, or a new `self_approved` record that record_self_approval writes at /task, /chat (moved from admission to the row's setup — the agent receives the row's id, not the capacity slot's) and the execute_task backstop. No migration: a new value in skill_gate_requests.state, outside the lattice. - A self-approved /chat turn runs in its own session (isolated_session), so the next caller never resumes a context with the skill loaded. - Marker synced at start/recreate (gated agents only), self-healed from the check (rate-limited) and serialised per agent; /health reports skill_gate_hook. - Review hardening: a skill or subagent definition whose name the hook cannot read (or an unterminated front matter) is "could not tell", never "not gated"; block-scalar names are read; no subagent_type means general-purpose (a definition may override it); CLAUDE_CONFIG_DIR from the claude env adds its dirs; refusal audits are capped per agent (the run id is the caller's); a logger that cannot start never changes the verdict. Every wired call site and each review fix was mutation-checked. Inert until ent#753 supplies the gate map. Stated limits in requirements/security.md §26.13 (Claude Code only; not a boundary against an adversarial executor — credential confinement is, R23 / ent#558). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ading slash never reaches it (Abilityai/trinity-enterprise#752) The localhost eyeball showed that Claude Code expands an approved or self-approved request that starts with /pay-invoice without any Skill call, so the hook is never asked about it; the dispatch-time check decides those. The hook's allow path is a Skill call inside the cleared run (a slash mid-sentence, or the model choosing the skill). - skill-gate.md Testing step 7 now uses the mid-sentence form for the approved and self-approved cases, adds the isolated /chat probe and the no-run case, replaces "stop the backend" (the chat itself goes through it) with a check route that answers 503, and saves the running base image before the build so the restore never downgrades the agents. - §26.13 and the flow's limits say what a clearance lets through. - "the session tab" is the Chat tab. - Status records the 2026-10-05 eyeball. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…l-hook Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…st-runner classifies its skip (Abilityai/trinity-enterprise#752) The skip matched no rule in test-runner's skip-patterns.txt and showed up as an unclassified warning in /verify-local's unit stage. Its skipif is exactly 'not Linux', so the reason now says so and the existing GATED:Linux only rule classifies it. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
) On a browser-claimed install (every one-click / marketplace path) the only system-agent deploy runs at boot, before /setup has created the admin, and fails with "Admin user 'admin' not found". Nothing retried it, so trinity-system stayed absent until a backend restart. /setup now schedules ensure_deployed() as a background task after the admin row is written, ahead of first-run seeding (the boot order; the seeder hosts its alerts on trinity-system). The task never raises, since Starlette runs background tasks in sequence, and skips without Docker. Fixes #3237 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…#2329 close-owner docstrings merge-train: expire_stale_queued writes FAILED and calls no closer, so the docstrings and the test docstring overstated coverage. Mechanical, per the merge-train note on the PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
merge-train: resolve docs/memory/feature-flows.md — keep both 2026-10-05 rows (ent#752 from this branch, ent#568 from dev). Mechanical, per the merge-train note on the PR. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Integration surface for #3261, #3181, #3227, #3252. Never merged; members merge individually once green.