fix(runtime-context): align controller role metadata and capability routing #950

Open
opened 2026-07-27 21:12:15 -05:00 by jcwalker3 · 0 comments
Owner

Related: #949, #723, #726, #714, #690, #540, #131, #722

Observed conflict

During native cross-LLM validation, the gitea-controller namespace returned internally conflicting identity metadata:

  • Active profile: prgs-controller
  • gitea_whoami.role_kind: controller
  • gitea_get_runtime_context.role_kind: reconciler
  • Runtime audit_label: prgs-reconciler
  • Repository binding remained the expected Gitea-Tools repository
  • Revision parity was green

Two sanctioned read-only identity surfaces on the same namespace, in the same session, disagreed about the assigned role. This proves an externally visible metadata or configuration-contract conflict. It does not, by itself, prove mixed processes or mixed revisions.

The audit could not establish whether this represents:

  • An intentional internal controller/reconciler implementation alias
  • An incorrect diagnostic label
  • An incorrect assigned role
  • A wrong profile binding
  • Mixed runtime/configuration
  • An unresolved capability-routing defect

A green revision-parity result must not automatically classify this mismatch as harmless. Parity proves the serving process is running the expected code; it proves nothing about whether that code reports the correct role. The two are independent gates.

Required behavior

For every native namespace, externally reported identity and runtime metadata must consistently distinguish:

  • Configured profile
  • Profile lock
  • Authenticated identity
  • Assigned role
  • Runtime implementation identity
  • Audit label
  • Repository binding
  • Capability-routing role

For gitea-controller, the public contract should consistently report the controller identity:

  • Profile: prgs-controller
  • Assigned role: controller
  • Runtime role: controller
  • Audit label: prgs-controller

If controller operations intentionally reuse reconciler internals, expose that separately as implementation provenance. Do not overwrite or mislabel the externally assigned controller role.

For gitea-reconciler, the public contract must continue reporting:

  • Profile: prgs-reconciler
  • Assigned role: reconciler
  • Runtime role: reconciler
  • Audit label: prgs-reconciler

Capability resolution

Capability resolution must distinguish clearly among:

  • Supported and allowed
  • Supported but denied for the current role
  • Unsupported
  • Unknown because runtime metadata is incomplete
  • Blocked by wrong profile or role binding
  • Blocked by stale or mixed runtime state

These are six distinct operator actions. Collapsing them into a single denial, a bare unknown_task, or an unstructured error forces an LLM to guess whether it hit a permission boundary, a missing map entry, or a runtime failure.

Investigate the previously ambiguous or unknown resolution of route_task_session.

  • If route_task_session is a valid controller capability, it must resolve deterministically through gitea-controller.
  • If it is not a valid public capability, return a structured unsupported result and identify the canonical replacement. Do not return ambiguous routing evidence that could be mistaken for a runtime failure.

Acceptance criteria

  1. gitea-controller.gitea_whoami and gitea-controller.gitea_get_runtime_context agree that the assigned public role is controller.
  2. The controller audit label identifies prgs-controller.
  3. The controller profile lock and active profile agree.
  4. Repository binding remains correct and consistent across identity and runtime calls.
  5. Intentional internal reconciler reuse, if present, is exposed in a separate implementation field.
  6. Internal implementation provenance cannot overwrite the assigned public role.
  7. gitea-reconciler continues reporting the reconciler profile and role correctly.
  8. Controller and reconciler capability resolution uses the appropriate assigned role.
  9. route_task_session resolves deterministically or returns a structured unsupported result with the canonical alternative.
  10. Wrong-profile, incorrect-role, and mixed-configuration states fail closed.
  11. Green revision parity does not suppress or excuse identity-contract mismatches.
  12. Automated tests cover controller identity, reconciler identity, intentional implementation aliasing, wrong profile binding, incorrect audit labels, and capability-resolution outcomes.
  13. Canonical workflow documentation explains the distinction between assigned role and implementation identity.
  14. An LLM can classify the namespace correctly using only sanctioned native calls.

Non-goals

Duplicate verdict

NOT a duplicate. Verified by reading the bodies and acceptance criteria of #949, #723, #726, #714, #690, #540, and #131.

Issue State Why it does not cover this
#949 open Owns authoritative fleet inventory and duplicate-process detection. Its non-goal list names "Repairing controller/reconciler role metadata" explicitly, so it disclaims this scope by construction. It answers how many processes exist and in which cohort; this issue answers what role a single namespace reports about itself.
#723 closed Capability map vs router vs runtime-context disagreement for the reviewer/merger formal-review task family, stemming from incident #722. Its acceptance criteria are scoped to role-exclusive review tasks, REVIEWER_TASKS/MERGER_TASKS invariants, and the internal_error escape in the submit path. It does not cover controller/reconciler aliasing, audit_label correctness, or route_task_session.
#726 open Scoped to adding acquire_reviewer_pr_lease to the capability map and returning a structured response instead of raising ValueError. That is one missing map entry plus error-shape hardening. It does not define the six-way resolution taxonomy above, does not cover route_task_session, and does not touch role metadata at all.
#714 closed Cross-host profile drift and substitution: a dadeschools pin silently resolving through prgs-author. The failure there is one profile being swapped for a different profile on another host. Here the profile binding is correct and stable; two surfaces within that one correct binding disagree about its role.
#690 open Formal-review session boundary hygiene after a mid-run cross-role profile activation. Requires re-preflight and state invalidation on a switch. No profile switch occurred in the observed conflict; the metadata disagreed on a single unswitched namespace.
#540 closed Nearest precedent in class: comment_issue preflight stamping _preflight_resolved_role="author" and defeating the #274 reconciler exemption. That is a per-task preflight stamp poisoning workspace-role classification for a mutation guard. This issue concerns the namespace's own reported public role in read-only identity surfaces, and adds the implementation-provenance separation that #540 never contemplated.
#131 closed The origin issue that introduced gitea_get_runtime_context and gitea_list_profiles. It specified that runtime context must report an active profile and role kind; it did not specify that the value must agree with gitea_whoami, nor define assigned role vs implementation identity.

Canonical issue state

STATE: ready-for-author
WHO_IS_NEXT: author
NEXT_ACTION: Align controller role metadata across gitea_whoami and gitea_get_runtime_context, separate implementation provenance from assigned public role, and make capability resolution outcomes structurally distinct
NEXT_PROMPT:
Role: AUTHOR
Repo: prgs / Scaled-Tech-Consulting / Gitea-Tools
Issue: this issue

1. Native MCP only; gitea_whoami + gitea_resolve_task_capability(work_issue) on prgs-author; bind an issue-backed worktree under branches/.
2. Reproduce the conflict: capture gitea-controller gitea_whoami.role_kind, gitea_get_runtime_context.role_kind, and audit_label in one session.
3. Determine whether the reconciler value is an intentional implementation alias or a defect, then implement the assigned-role vs implementation-provenance separation per the acceptance criteria.
4. Make capability resolution distinguish allowed, denied-for-role, unsupported, unknown-metadata, wrong-binding, and stale-runtime outcomes; settle route_task_session deterministically or as structured unsupported with a canonical alternative.
5. Add regression tests for controller identity, reconciler identity, intentional aliasing, wrong profile binding, incorrect audit labels, and every capability-resolution outcome.
6. Update canonical workflow documentation on assigned role vs implementation identity.
7. Open a PR with Closes; stop; hand off to an independent reviewer.
Related: #949, #723, #726, #714, #690, #540, #131, #722 ## Observed conflict During native cross-LLM validation, the `gitea-controller` namespace returned internally conflicting identity metadata: * Active profile: `prgs-controller` * `gitea_whoami.role_kind`: `controller` * `gitea_get_runtime_context.role_kind`: `reconciler` * Runtime `audit_label`: `prgs-reconciler` * Repository binding remained the expected Gitea-Tools repository * Revision parity was green Two sanctioned read-only identity surfaces on the same namespace, in the same session, disagreed about the assigned role. This proves an externally visible metadata or configuration-contract conflict. It does **not**, by itself, prove mixed processes or mixed revisions. The audit could not establish whether this represents: * An intentional internal controller/reconciler implementation alias * An incorrect diagnostic label * An incorrect assigned role * A wrong profile binding * Mixed runtime/configuration * An unresolved capability-routing defect A green revision-parity result must not automatically classify this mismatch as harmless. Parity proves the serving process is running the expected code; it proves nothing about whether that code reports the correct role. The two are independent gates. ## Required behavior For every native namespace, externally reported identity and runtime metadata must consistently distinguish: * Configured profile * Profile lock * Authenticated identity * Assigned role * Runtime implementation identity * Audit label * Repository binding * Capability-routing role For `gitea-controller`, the public contract should consistently report the controller identity: * Profile: `prgs-controller` * Assigned role: `controller` * Runtime role: `controller` * Audit label: `prgs-controller` If controller operations intentionally reuse reconciler internals, expose that separately as implementation provenance. Do not overwrite or mislabel the externally assigned controller role. For `gitea-reconciler`, the public contract must continue reporting: * Profile: `prgs-reconciler` * Assigned role: `reconciler` * Runtime role: `reconciler` * Audit label: `prgs-reconciler` ## Capability resolution Capability resolution must distinguish clearly among: * Supported and allowed * Supported but denied for the current role * Unsupported * Unknown because runtime metadata is incomplete * Blocked by wrong profile or role binding * Blocked by stale or mixed runtime state These are six distinct operator actions. Collapsing them into a single denial, a bare `unknown_task`, or an unstructured error forces an LLM to guess whether it hit a permission boundary, a missing map entry, or a runtime failure. Investigate the previously ambiguous or unknown resolution of `route_task_session`. * If `route_task_session` is a valid controller capability, it must resolve deterministically through `gitea-controller`. * If it is not a valid public capability, return a structured unsupported result and identify the canonical replacement. Do not return ambiguous routing evidence that could be mistaken for a runtime failure. ## Acceptance criteria 1. `gitea-controller.gitea_whoami` and `gitea-controller.gitea_get_runtime_context` agree that the assigned public role is `controller`. 2. The controller audit label identifies `prgs-controller`. 3. The controller profile lock and active profile agree. 4. Repository binding remains correct and consistent across identity and runtime calls. 5. Intentional internal reconciler reuse, if present, is exposed in a separate implementation field. 6. Internal implementation provenance cannot overwrite the assigned public role. 7. `gitea-reconciler` continues reporting the reconciler profile and role correctly. 8. Controller and reconciler capability resolution uses the appropriate assigned role. 9. `route_task_session` resolves deterministically or returns a structured unsupported result with the canonical alternative. 10. Wrong-profile, incorrect-role, and mixed-configuration states fail closed. 11. Green revision parity does not suppress or excuse identity-contract mismatches. 12. Automated tests cover controller identity, reconciler identity, intentional implementation aliasing, wrong profile binding, incorrect audit labels, and capability-resolution outcomes. 13. Canonical workflow documentation explains the distinction between assigned role and implementation identity. 14. An LLM can classify the namespace correctly using only sanctioned native calls. ## Non-goals * Authoritative fleet discovery or duplicate-process detection; tracked separately by #949 * Restart or synchronization provenance * Restarting or reconnecting the fleet * Cleaning the stale PR #906 author lease * Resuming #931 * Implementing PR #942 cleanup * Changing controller or reconciler permissions unless required to restore the documented role contract ## Duplicate verdict NOT a duplicate. Verified by reading the bodies and acceptance criteria of #949, #723, #726, #714, #690, #540, and #131. | Issue | State | Why it does not cover this | | --- | --- | --- | | #949 | open | Owns authoritative fleet inventory and duplicate-process detection. Its non-goal list names "Repairing controller/reconciler role metadata" explicitly, so it disclaims this scope by construction. It answers *how many processes exist and in which cohort*; this issue answers *what role a single namespace reports about itself*. | | #723 | closed | Capability map vs router vs runtime-context disagreement for the **reviewer/merger** formal-review task family, stemming from incident #722. Its acceptance criteria are scoped to role-exclusive review tasks, `REVIEWER_TASKS`/`MERGER_TASKS` invariants, and the `internal_error` escape in the submit path. It does not cover controller/reconciler aliasing, `audit_label` correctness, or `route_task_session`. | | #726 | open | Scoped to adding `acquire_reviewer_pr_lease` to the capability map and returning a structured response instead of raising `ValueError`. That is one missing map entry plus error-shape hardening. It does not define the six-way resolution taxonomy above, does not cover `route_task_session`, and does not touch role metadata at all. | | #714 | closed | Cross-**host** profile drift and substitution: a `dadeschools` pin silently resolving through `prgs-author`. The failure there is one profile being swapped for a different profile on another host. Here the profile binding is correct and stable; two surfaces within that one correct binding disagree about its role. | | #690 | open | Formal-review session boundary hygiene after a mid-run cross-role profile *activation*. Requires re-preflight and state invalidation on a switch. No profile switch occurred in the observed conflict; the metadata disagreed on a single unswitched namespace. | | #540 | closed | Nearest precedent in class: `comment_issue` preflight stamping `_preflight_resolved_role="author"` and defeating the #274 reconciler exemption. That is a per-task preflight stamp poisoning workspace-role classification for a mutation guard. This issue concerns the namespace's own reported public role in read-only identity surfaces, and adds the implementation-provenance separation that #540 never contemplated. | | #131 | closed | The origin issue that introduced `gitea_get_runtime_context` and `gitea_list_profiles`. It specified that runtime context must report an active profile and role kind; it did not specify that the value must agree with `gitea_whoami`, nor define assigned role vs implementation identity. | ## Canonical issue state ```text STATE: ready-for-author WHO_IS_NEXT: author NEXT_ACTION: Align controller role metadata across gitea_whoami and gitea_get_runtime_context, separate implementation provenance from assigned public role, and make capability resolution outcomes structurally distinct NEXT_PROMPT: Role: AUTHOR Repo: prgs / Scaled-Tech-Consulting / Gitea-Tools Issue: this issue 1. Native MCP only; gitea_whoami + gitea_resolve_task_capability(work_issue) on prgs-author; bind an issue-backed worktree under branches/. 2. Reproduce the conflict: capture gitea-controller gitea_whoami.role_kind, gitea_get_runtime_context.role_kind, and audit_label in one session. 3. Determine whether the reconciler value is an intentional implementation alias or a defect, then implement the assigned-role vs implementation-provenance separation per the acceptance criteria. 4. Make capability resolution distinguish allowed, denied-for-role, unsupported, unknown-metadata, wrong-binding, and stale-runtime outcomes; settle route_task_session deterministically or as structured unsupported with a canonical alternative. 5. Add regression tests for controller identity, reconciler identity, intentional aliasing, wrong profile binding, incorrect audit labels, and every capability-resolution outcome. 6. Update canonical workflow documentation on assigned role vs implementation identity. 7. Open a PR with Closes; stop; hand off to an independent reviewer. ```
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#950