fix(manager): cotal attach gives runtime-correct hint (cmux ≠ tmux)#30
Open
Lanzelot1 wants to merge 2 commits into
Open
fix(manager): cotal attach gives runtime-correct hint (cmux ≠ tmux)#30Lanzelot1 wants to merge 2 commits into
Lanzelot1 wants to merge 2 commits into
Conversation
opAttach assumed non-pty == tmux, so cmux users got a tmux attach command. Delegate to the handle's own attach() so each runtime speaks for itself (tmux → tmux attach -t …; cmux → switch to the cotal-<name> tab). Add pnpm smoke:attach covering pty/tmux/cmux, and sharpen the docs. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
davidfarah2003
added a commit
that referenced
this pull request
Jul 16, 2026
…est subject (B1 structural half) Closes the structural half of the mediator authority-boundary blocker (fact-3/distsys B1): the obligation coordinate's caller identity is no longer a public argument. - obtain* now take a BRANDED MediatedRequest built by mediatedRequestFromSubject(subject), which parses the endpoint + caller triple STRUCTURALLY from an authenticated ep/epj request subject through core's parseEpSubject. A hand-assembled request never authorizes (WeakSet brand), and a request whose subject names a different endpoint is refused by this mediator. The caller-chosen request id (a body field, per 13.4) stays an explicit op argument; everything identifying WHO the caller is comes from the subject. - AdmissionIdentity split into MediatedRequest (subject-derived identity) and AdmissionOp (target/policy/id operation coordinates). Smoke 42/42: the obligation key embeds the subject-derived caller triple; a hand-assembled request and a foreign-endpoint request both refuse; a non-request subject refuses at construction. Temp-revert of the brand check fails exactly those two probes. Full smoke:ci green. Still open: the scoped admission-mediator credential profile + confinement smoke (B1's broker-enforcement half), tracked task #30.
davidfarah2003
added a commit
that referenced
this pull request
Jul 16, 2026
…finement probe (D14 slice a) The two 13.9 ownership-matrix rows whose residual is "explicit per D32" get their grant builders and a live broker probe (the B1 broker half, task #30; the first D14/D32 slice): - admissionMediatorGrants (core, endpoint-binding): the endpoint's oblig.*.<e>.> CAS writes, the endpoint-literal terminal-rejection decision publish, the fencing leader reads (records/EPF/EPW STREAM.MSG.GET), the 13.12 bind-time shape proof (records STREAM.INFO), and the per-run enumeration consumer whose CREATE row PINS the filter to the endpoint's own oblig subtree. No CONSUMER.DELETE row: the throwaway scan is collected by its own inactive_threshold, and a delete grant would reach every records consumer by name. The three D32 residuals are stated on the builder: the own-endpoint ACCEPTANCE-forge (rejection-only is not subject-expressible: both decisions share the create-only decision subject for first-wins settlement), the space-wide body-selected MSG.GET read exposure, and the name-wildcard enumeration consumer. - retirementCleanerGrants (core): per LISTED pool only (never a wildcard), bind-only durable rows + the pool-scoped wrk terminal publish, plus the space-wide EPF MSG.GET terminal-observe read (explicit per D32); no epw publish, no consumer create/update/delete, no stream delete. - SPEC 13.9: the acceptance-obligation row now NAMES the own-endpoint acceptance-forge residual verbatim (an escalation to injecting executed work, never merely reject/stall), per the security lane's requirement; docs bundle regenerated. The confinement smoke (mediator-confinement, 26 checks, live broker with plain user authorization built FROM the builders): the REAL mediator runs over the scoped credential end-to-end with its obligation identity fed from a LIVE broker-delivered subject (a subscription's msg.subject into mediatedRequestFromSubject, closing the "inert structural half" gap), wins the create-fence, settles, and emits a core-valid rejection; the REAL exact-pool cleaner reaches proven quiescence over its scoped credential. Denials, broker-enforced on the same credentials: cross-endpoint decision forge, foreign oblig subtree, govern head, auth store, foreign-filter enumeration consumer, records message-delete/purge, Direct Get, pool enqueue (mediator); non-listed pool wrk, any decision publish, epw enqueue, foreign durable bind, consumer create/delete, stream purge, EPW leader read, records writes (cleaner). The own-endpoint decision publish is asserted POSSIBLE, so the named D32 residual is proven present rather than silently implied absent. Wired into smoke:ci; full gate green. The provision-path mint wiring (which authority mints these profiles, gate-fenced) intentionally rides the production activation slice; the rows and their broker enforcement are what this slice pins.
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.
Problem
Running
cotal attach --name <agent>against a cmux-runtime agent printed a tmux instruction:cmux is not tmux — it's a standalone GUI multiplexer with its own CLI — so that hint is wrong and confuses users (seen in the wild).
opAttachonly special-casedptyand assumed every other runtime was tmux;cmuxwas added later and fell into the tmux branch.Fix
opAttach(implementations/manager/src/manager.ts) now delegates to the agent handle's ownattach(), so each runtime gives its own guidance:pty→ streams over the WS attach endpoint (unchanged)tmux→tmux attach -t cotal-<space>:<name>cmux→switch to the "cotal-<name>" cmux tabAlso sharpens the runtime section in
docs/architecture.mdand addspnpm smoke:attachcovering all three runtimes.Testing
pnpm --filter @cotal-ai/manager --filter @cotal-ai/cmux typecheck— cleanpnpm smoke:attach— pty/tmux/cmux all pass (cmux opened+closed a real tab)cotal cmux --spawn …thencotal attach→cmux runtime: switch to the "cotal-<name>" cmux tab to watch it(no tmux text)🤖 Generated with Claude Code