Production launcher cannot issue trusted client-instance identity for project-scoped LLM launches #985

Open
opened 2026-07-31 02:39:43 -05:00 by jcwalker3 · 2 comments
Owner

Problem

The fleet-safety implementation requires each application launch to receive one trusted, unique GITEA_MCP_CLIENT_INSTANCE, shared by every MCP namespace worker belonging to that launch.

Current MCP configurations bypass the launcher API and omit trusted instance identity. Workers fall back to legacy-pid-*, which is intentionally classified as legacy_incomplete. When multiple LLM applications run concurrently, workers using the same profile become indistinguishable and capability resolution fails closed with runtime_reconnect_required.

The existing launcher cannot fully remediate this:

  1. build_application_mcp_servers requires profiles for all five sanctioned namespaces.
  2. Project-scoped configurations such as Weekly Briefings expose only author, reviewer, and merger; they intentionally have no controller or reconciler profiles.
  3. The launcher produces configuration data but provides no sanctioned runnable entry point that starts Claude Code or another supported LLM client with a freshly minted identity.
  4. Storing a static identity in .mcp.json would cause concurrent sessions to reuse one trusted identity and trigger the stricter duplicate-worker failure.

Required behavior

  • Support an explicitly validated subset of sanctioned namespaces.
  • Preserve the existing five-namespace launch behavior.
  • Provide a supported runnable launch path for Claude Code CLI.
  • Design the launch interface so other supported clients can use the same mechanism.
  • Mint exactly one trusted client-instance ID per application launch.
  • Propagate that same ID to every namespace worker belonging to that launch.
  • Give separate concurrent application launches distinct IDs.
  • Set launcher-sealed trusted provenance through the sanctioned mechanism.
  • Avoid persistent or static per-project instance IDs.
  • Preserve fail-closed behavior for missing, untrusted, reused, or conflicting identities.
  • Do not weaken duplicate-worker detection or permit manually asserted trust.

Acceptance criteria

  • A three-namespace launch for author, reviewer, and merger succeeds without requiring controller or reconciler profiles.
  • All workers from one launch report the same trusted instance ID.
  • Two concurrent launches receive different trusted instance IDs.
  • Two concurrent launches using the same profile are distinguishable and do not produce a false duplicate-worker blocker.
  • Reuse of one trusted ID by multiple live application launches still fails closed.
  • Missing or legacy-pid-* identity still fails closed when processes cannot be distinguished safely.
  • Existing full five-namespace behavior remains compatible.
  • Claude Code has a documented supported launch command.
  • Tests cover namespace subsets, identity sharing, concurrent uniqueness, unsafe reuse, legacy fallback, and backward compatibility.
  • Documentation explains migration, coordinated relaunch, and post-launch verification.

Source references

Out of scope

  • Static identities in .mcp.json
  • Weakening fleet or duplicate-process gates
  • Killing legitimate concurrent LLM processes
  • Weekly Briefings repository guard #741
  • Creating MDCPS controller or reconciler profiles
  • Changing credentials or repository authorization
## Problem The fleet-safety implementation requires each application launch to receive one trusted, unique `GITEA_MCP_CLIENT_INSTANCE`, shared by every MCP namespace worker belonging to that launch. Current MCP configurations bypass the launcher API and omit trusted instance identity. Workers fall back to `legacy-pid-*`, which is intentionally classified as `legacy_incomplete`. When multiple LLM applications run concurrently, workers using the same profile become indistinguishable and capability resolution fails closed with `runtime_reconnect_required`. The existing launcher cannot fully remediate this: 1. `build_application_mcp_servers` requires profiles for all five sanctioned namespaces. 2. Project-scoped configurations such as Weekly Briefings expose only author, reviewer, and merger; they intentionally have no controller or reconciler profiles. 3. The launcher produces configuration data but provides no sanctioned runnable entry point that starts Claude Code or another supported LLM client with a freshly minted identity. 4. Storing a static identity in `.mcp.json` would cause concurrent sessions to reuse one trusted identity and trigger the stricter duplicate-worker failure. ## Required behavior * Support an explicitly validated subset of sanctioned namespaces. * Preserve the existing five-namespace launch behavior. * Provide a supported runnable launch path for Claude Code CLI. * Design the launch interface so other supported clients can use the same mechanism. * Mint exactly one trusted client-instance ID per application launch. * Propagate that same ID to every namespace worker belonging to that launch. * Give separate concurrent application launches distinct IDs. * Set launcher-sealed trusted provenance through the sanctioned mechanism. * Avoid persistent or static per-project instance IDs. * Preserve fail-closed behavior for missing, untrusted, reused, or conflicting identities. * Do not weaken duplicate-worker detection or permit manually asserted trust. ## Acceptance criteria * A three-namespace launch for author, reviewer, and merger succeeds without requiring controller or reconciler profiles. * All workers from one launch report the same trusted instance ID. * Two concurrent launches receive different trusted instance IDs. * Two concurrent launches using the same profile are distinguishable and do not produce a false duplicate-worker blocker. * Reuse of one trusted ID by multiple live application launches still fails closed. * Missing or `legacy-pid-*` identity still fails closed when processes cannot be distinguished safely. * Existing full five-namespace behavior remains compatible. * Claude Code has a documented supported launch command. * Tests cover namespace subsets, identity sharing, concurrent uniqueness, unsafe reuse, legacy fallback, and backward compatibility. * Documentation explains migration, coordinated relaunch, and post-launch verification. ## Source references * `mcp_application_launcher.py` * `mcp_fleet_snapshot.py` * `gitea_mcp_server.py` * `gitea_config.py` * `gitea_config_menu.py` * `docs/instance-fleet-identity.md` * `tests/test_issue_978_instance_fleet_snapshot.py` * Refs #978 ## Out of scope * Static identities in `.mcp.json` * Weakening fleet or duplicate-process gates * Killing legitimate concurrent LLM processes * Weekly Briefings repository guard #741 * Creating MDCPS controller or reconciler profiles * Changing credentials or repository authorization
jcwalker3 added the mcparchitecturetype:featurestatus:readysafetycontrol-plane labels 2026-07-31 02:39:44 -05:00
jcwalker3 added status:in-progress and removed status:ready labels 2026-07-31 02:48:53 -05:00
Author
Owner

Issue claim heartbeat

<!-- gitea-issue-claim-heartbeat:v1 --> **Issue claim heartbeat** - kind: claim - issue: #985 - branch: feat/issue-985-project-scoped-launcher-identity - phase: claimed - profile: prgs-author - pr: none - blocker: none - next_action: create worktree and begin implementation
jcwalker3 added status:pr-open and removed status:in-progress labels 2026-07-31 03:20:31 -05:00
Author
Owner

Canonical Issue State

STATE: pr-open-awaiting-independent-review
WHO_IS_NEXT: reviewer
NEXT_ACTION: Review PR #986 at exact head 7e19079b5c against the #985 acceptance criteria and submit exactly one formal verdict at that head.
NEXT_PROMPT: Role REVIEWER on prgs / Scaled-Tech-Consulting / Gitea-Tools; target PR #986 at head 7e19079b5cc6b029aed729945c91e9edc5a1c721; full prompt below.

Role: REVIEWER
Repo: prgs / Scaled-Tech-Consulting / Gitea-Tools
Target: PR #986 (Closes #985) at exact head 7e19079b5cc6b029aed729945c91e9edc5a1c721

1. Native MCP only through the gitea-reviewer namespace. Run gitea_whoami, then
   gitea_load_review_workflow, then gitea_resolve_task_capability(review_pr).
2. Bind a branches/ worktree at the PR head; re-pin the live head before any verdict.
3. Confirm the provenance sealing change is correct: a well-formed inst- identity
   without GITEA_MCP_INSTANCE_PROVENANCE=trusted_launcher is now classified
   unsealed_launcher and refused. Trace it through _client_identity_hints.
4. Confirm the tests/test_issue_978_instance_fleet_snapshot.py edit tightened the
   contract rather than weakening an assertion; a companion test asserting the
   unsealed case fails closed was added alongside it.
5. Confirm resolve_launch_namespaces refuses unknown, duplicate, and empty
   selections, and that excluded namespaces are never started.
6. Decide the open question: whether per-launch temporary configs need an explicit
   cleanup owner in long-lived sessions.
7. Submit exactly one verdict at the current head. Do not merge.

WHAT_HAPPENED: Issue #985 was claimed under a canonical author issue lock, implemented on branch feat/issue-985-project-scoped-launcher-identity, published as commit 7e19079b5c, and opened as PR #986 against master carrying a Closes #985 reference; issue #985 transitioned to status:pr-open. Six files changed: mcp_application_launcher.py, mcp_fleet_snapshot.py, gitea_config.py, docs/instance-fleet-identity.md, tests/test_issue_978_instance_fleet_snapshot.py, and the new tests/test_issue_985_project_scoped_launcher.py. Three behavioural changes landed: build_application_mcp_servers now accepts an explicitly checked project-scoped namespace subset so an author/reviewer/merger launch needs no controller or reconciler profile; a runnable entry point mints one trusted GITEA_MCP_CLIENT_INSTANCE per launch, writes a per-launch 0600 config, and execs the client; and launcher provenance sealing now fails closed.
WHY: The author phase is finished and the prgs-author profile forbids gitea.pr.approve and gitea.pr.merge, confirmed via gitea_check_pr_eligibility, so only an independent reviewer can decide this PR.
RELATED_PRS: PR #986 carries this work and closes #985. Context only, not dependencies: issue #978 and its PR #979 introduced the instance-fleet snapshot this builds on; issues #980 and #981 each explicitly placed trusted launcher identity outside their own scope.
BLOCKERS: No blocker. No gate is refusing anything; the author lock is released and PR #986 awaits an independent reviewer decision, which is the normal next transition.
VALIDATION: tests/test_issue_985_project_scoped_launcher.py reports 47 passed and 3 subtests passed. Full suite on this branch reports 28 failed, 6252 passed, 6 skipped, 1109 subtests passed. Full suite on the master baseline at 32ab8392 reports 28 failed, 6204 passed, 6 skipped, 1106 subtests passed. The sorted FAILED sets are byte-identical between the two runs, so zero regressions were introduced and zero pre-existing failures were masked; the +48 passing delta is 47 new #985 tests plus the new #978 unsealed-case test.
LAST_UPDATED_BY: jcwalker3 (prgs-author) author handoff

[THREAD STATE LEDGER]

What is true now

Server-side decision state: PR #986 is open and mergeable with zero reviews recorded at head 7e19079b5cc6b029aed729945c91e9edc5a1c721; no approval, no requested changes, and no merge exists.
Local verdict/state: author implementation is finished, committed, and published; no review verdict exists locally or server-side because prgs-author forbids gitea.pr.approve and gitea.pr.merge.
Blocker classification: no blocker

What changed

Branch feat/issue-985-project-scoped-launcher-identity was created from master 32ab839289, six files were changed, and commit 7e19079b5c was published and opened as PR #986. Issue #985 moved to status:pr-open.

What is blocked

Blocker classification: no blocker

Nothing is impeded. The author lock is released and the cycle advances to independent review.

Who/what acts next

Next actor: reviewer (prgs-reviewer namespace, independent session)
Required action: review PR #986 at head 7e19079b5c and submit exactly one formal verdict at that head.

Do not do: approve, request changes on, or merge PR #986 using the author namespace; re-run the author workflow for #985; modify unrelated issues, PRs, branches, worktrees, labels, or configuration; attribute the 28 pre-existing full-suite failures to this PR.

## Canonical Issue State STATE: pr-open-awaiting-independent-review WHO_IS_NEXT: reviewer NEXT_ACTION: Review PR #986 at exact head 7e19079b5cc6b029aed729945c91e9edc5a1c721 against the #985 acceptance criteria and submit exactly one formal verdict at that head. NEXT_PROMPT: Role REVIEWER on prgs / Scaled-Tech-Consulting / Gitea-Tools; target PR #986 at head 7e19079b5cc6b029aed729945c91e9edc5a1c721; full prompt below. ```text Role: REVIEWER Repo: prgs / Scaled-Tech-Consulting / Gitea-Tools Target: PR #986 (Closes #985) at exact head 7e19079b5cc6b029aed729945c91e9edc5a1c721 1. Native MCP only through the gitea-reviewer namespace. Run gitea_whoami, then gitea_load_review_workflow, then gitea_resolve_task_capability(review_pr). 2. Bind a branches/ worktree at the PR head; re-pin the live head before any verdict. 3. Confirm the provenance sealing change is correct: a well-formed inst- identity without GITEA_MCP_INSTANCE_PROVENANCE=trusted_launcher is now classified unsealed_launcher and refused. Trace it through _client_identity_hints. 4. Confirm the tests/test_issue_978_instance_fleet_snapshot.py edit tightened the contract rather than weakening an assertion; a companion test asserting the unsealed case fails closed was added alongside it. 5. Confirm resolve_launch_namespaces refuses unknown, duplicate, and empty selections, and that excluded namespaces are never started. 6. Decide the open question: whether per-launch temporary configs need an explicit cleanup owner in long-lived sessions. 7. Submit exactly one verdict at the current head. Do not merge. ``` WHAT_HAPPENED: Issue #985 was claimed under a canonical author issue lock, implemented on branch feat/issue-985-project-scoped-launcher-identity, published as commit 7e19079b5cc6b029aed729945c91e9edc5a1c721, and opened as PR #986 against master carrying a Closes #985 reference; issue #985 transitioned to status:pr-open. Six files changed: mcp_application_launcher.py, mcp_fleet_snapshot.py, gitea_config.py, docs/instance-fleet-identity.md, tests/test_issue_978_instance_fleet_snapshot.py, and the new tests/test_issue_985_project_scoped_launcher.py. Three behavioural changes landed: build_application_mcp_servers now accepts an explicitly checked project-scoped namespace subset so an author/reviewer/merger launch needs no controller or reconciler profile; a runnable entry point mints one trusted GITEA_MCP_CLIENT_INSTANCE per launch, writes a per-launch 0600 config, and execs the client; and launcher provenance sealing now fails closed. WHY: The author phase is finished and the prgs-author profile forbids gitea.pr.approve and gitea.pr.merge, confirmed via gitea_check_pr_eligibility, so only an independent reviewer can decide this PR. RELATED_PRS: PR #986 carries this work and closes #985. Context only, not dependencies: issue #978 and its PR #979 introduced the instance-fleet snapshot this builds on; issues #980 and #981 each explicitly placed trusted launcher identity outside their own scope. BLOCKERS: No blocker. No gate is refusing anything; the author lock is released and PR #986 awaits an independent reviewer decision, which is the normal next transition. VALIDATION: tests/test_issue_985_project_scoped_launcher.py reports 47 passed and 3 subtests passed. Full suite on this branch reports 28 failed, 6252 passed, 6 skipped, 1109 subtests passed. Full suite on the master baseline at 32ab8392 reports 28 failed, 6204 passed, 6 skipped, 1106 subtests passed. The sorted FAILED sets are byte-identical between the two runs, so zero regressions were introduced and zero pre-existing failures were masked; the +48 passing delta is 47 new #985 tests plus the new #978 unsealed-case test. LAST_UPDATED_BY: jcwalker3 (prgs-author) author handoff [THREAD STATE LEDGER] ## What is true now Server-side decision state: PR #986 is open and mergeable with zero reviews recorded at head 7e19079b5cc6b029aed729945c91e9edc5a1c721; no approval, no requested changes, and no merge exists. Local verdict/state: author implementation is finished, committed, and published; no review verdict exists locally or server-side because prgs-author forbids gitea.pr.approve and gitea.pr.merge. Blocker classification: no blocker ## What changed Branch feat/issue-985-project-scoped-launcher-identity was created from master 32ab839289e6efffa5cbfe978af30178b53d63ab, six files were changed, and commit 7e19079b5cc6b029aed729945c91e9edc5a1c721 was published and opened as PR #986. Issue #985 moved to status:pr-open. ## What is blocked Blocker classification: no blocker Nothing is impeded. The author lock is released and the cycle advances to independent review. ## Who/what acts next Next actor: reviewer (prgs-reviewer namespace, independent session) Required action: review PR #986 at head 7e19079b5cc6b029aed729945c91e9edc5a1c721 and submit exactly one formal verdict at that head. Do not do: approve, request changes on, or merge PR #986 using the author namespace; re-run the author workflow for #985; modify unrelated issues, PRs, branches, worktrees, labels, or configuration; attribute the 28 pre-existing full-suite failures to this PR.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Scaled-Tech-Consulting/Gitea-Tools#985