Skip to content

refactor(decision-context): classify the two capability id slots and single-source the kunluncode mcp pin - #4511

Closed
BigDataDZ wants to merge 2 commits into
loopx-project:mainfrom
BigDataDZ:codex/4447-capability-id-and-mcp-pin
Closed

BigDataDZ wants to merge 2 commits into
loopx-project:mainfrom
BigDataDZ:codex/4447-capability-id-and-mcp-pin

Conversation

@BigDataDZ

Copy link
Copy Markdown
Contributor

Refs #4447 — Track A, the checklist item:
"Resolve DECISION_CONTEXT_CAPABILITY_ID hyphen/underscore and MCP_REQUIREMENT pin/range differences after checking actual callers and packaging boundaries."

This PR does not close the tracker; it addresses two checklist items and records the classification evidence for both.

1. DECISION_CONTEXT_CAPABILITY_ID — two slots, not a conflict

The same constant name carried two values:

Module Value Slot
capabilities/decision_context/extension_provider.py:24 decision-context extension binding
capabilities/decision_context/packets.py:18 decision_context capability packet contract

Caller check shows both spellings are conventional in their own namespace and neither is a stray:

  • hyphen is the catalog/CLI/extension namespace — all 21 loopx/capabilities/*/catalog_entry.py ids use it (decision-context, material-lifecycle, periodic-report, …), matching the CLI command and the decision-context help/catalog surface. The extension value is looked up by the extension runtime, so it must equal DECISION_CONTEXT_CATALOG_ENTRY["id"].
  • underscore is the packet-contract namespace — the sibling capability emits material_lifecycle (capabilities/material_lifecycle/architecture.py:39, _validation.py:177), and the six decision-context emitters (architecture.py:33, profile.py:419, runtime.py:321, sources.py:314 and :401, outcome_feedback.py:301) all agree.

No consumer joins the two values, so both values are retained and the constants are renamed to name their slot: DECISION_CONTEXT_EXTENSION_CAPABILITY_ID and DECISION_CONTEXT_PACKET_CAPABILITY_ID. Values, packet output and extension lookup behaviour are unchanged. This is a scope clarification, not a debt-count reduction.

2. MCP_REQUIREMENT — pin vs range is justified; the same-file triplication was not

  • loopx/kunluncode_goal_mode/cli.py:28 → mcp==1.28.1 (exact)
  • loopx/claude_goal_mode/scripts/install.py:83 → mcp<2 (range)

The difference is justified and is kept: the two adapters provision separate venvs (~/.local/share/loopx/kunluncode-mcp/.venv vs the Claude MCP venv), so they are separate packaging boundaries. The exact pin is also deliberate — loopx/goal_mode_mcp.py:285 imports mcp.server.fastmcp, which the MCP SDK 2.x line no longer ships, and the pin came from 892faa2c9 fix(security): upgrade the MCP SDK pin. Relaxing it to a range would undo a security pin.

The real defect was local: 1.28.1 was written out three times in cli.py — in MCP_REQUIREMENT, in the _compatible_python probe assertion, and in the provisioning failure message. A bump could update the requirement while leaving a probe that asserts the old version. MCP_SDK_VERSION is now the single source; the requirement, probe and message derive from it.

Validation

Base 36c6d8df0 (upstream/main), head 531a611f3. Python 3.13.12 (repo requires >=3.11; no python3.11 on this machine).

Command Result
pytest -q tests/capabilities/test_decision_context_capability_id_slots.py tests/test_kunluncode_goal_mode.py tests/capabilities/test_decision_context_packets.py tests/capabilities/test_decision_context_extension_provider.py 80 passed
pytest -q tests/capabilities 1436 passed, 17 skipped, 9 failed — identical 9 on clean base, all in test_repository_change_window.py (SSH/worktree env), untouched by this PR
pytest -q tests/architecture 177 passed, 24 failed — identical 24 on clean base, all TypeScript-parser cases
ruff check on all changed files clean
examples/semantic-vocabulary-drift-smoke.py fails on base too: TypeScript production parser failed; run npm ci. Not runnable here, unchanged by this PR

Boundaries

  • No runtime, wire or persisted-format change; no value in any packet or extension lookup changes.
  • The RFC census lines (semantic-vocabulary-convergence-v0.md:110 / .zh-CN.md:95) still list DECISION_CONTEXT_CAPABILITY_ID as a same-name conflict. They are now historically resolved; I left the normative bilingual RFCs alone so the update can be recorded as a decision rather than smuggled into a code PR.
  • Both commits carry DCO Signed-off-by.

Refs loopx-project#4447 (Track A)

DECISION_CONTEXT_CAPABILITY_ID was defined twice with different values:
"decision-context" for the extension binding and "decision_context" for
the capability packet contract. They are not a conflict:

* the hyphenated value is the catalog/CLI/extension namespace, and every
  loopx/capabilities/*/catalog_entry.py id uses that spelling;
* the underscore value is the packet contract, matching the sibling
  capability's "material_lifecycle".

No consumer joins the two, so both values are retained and the constants
now name their slot. Bump-safe parity is locked by a focused regression
test instead of a unification that would break either namespace.

Signed-off-by: BigDataDZ <76271875+BigDataDZ@users.noreply.github.com>
Refs loopx-project#4447 (Track A)

The pinned mcp version was written out three times in cli.py: in
MCP_REQUIREMENT, in the _compatible_python probe and in the provision
failure message. A future pin bump could therefore update the install
requirement while leaving a probe that still asserts the old version.

MCP_SDK_VERSION is now the only place the version appears; the
requirement, the probe and the message all derive from it. The pin stays
exact and is not relaxed to a range: goal_mode_mcp.py imports
mcp.server.fastmcp, which the MCP SDK 2.x line no longer ships, and the
pin is a deliberate security pin (892faa2). It also stays independent
of claude_goal_mode's "mcp<2": the two adapters provision separate venvs,
so they are separate packaging boundaries.

Signed-off-by: BigDataDZ <76271875+BigDataDZ@users.noreply.github.com>
@BigDataDZ

Copy link
Copy Markdown
Contributor Author

Superseded by #4513: same two Track A items, re-pushed from the YZJF fork so the contribution lands under that account. Closing to avoid a duplicate review.

@BigDataDZ BigDataDZ closed this Sep 16, 2026
@BigDataDZ
BigDataDZ deleted the codex/4447-capability-id-and-mcp-pin branch September 16, 2026 08:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant