Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 87172229aa | |||
| e88ca1d64b | |||
| 4253f8a52a | |||
| cd1d8d71a2 |
@@ -221,6 +221,12 @@ Canonical profile file (e.g. `~/.config/gitea-tools/profiles.json`):
|
|||||||
"username": "913443",
|
"username": "913443",
|
||||||
"auth": { "type": "env", "name": "GITEA_TOKEN_MDCPS" },
|
"auth": { "type": "env", "name": "GITEA_TOKEN_MDCPS" },
|
||||||
"execution_profile": "mdcps"
|
"execution_profile": "mdcps"
|
||||||
|
},
|
||||||
|
"mdcps-reviewer": {
|
||||||
|
"base_url": "https://gitea.dadeschools.net",
|
||||||
|
"username": "913443",
|
||||||
|
"auth": { "type": "keychain", "id": "mdcps.gitea.reviewer.token" },
|
||||||
|
"execution_profile": "mdcps-reviewer"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,16 +18,17 @@ behavior they rely on already exists (canonical runtime profiles, the
|
|||||||
interactive setup menu, identity/eligibility checks, gated review/merge, and
|
interactive setup menu, identity/eligibility checks, gated review/merge, and
|
||||||
audit logging). See [Related documents](#related-documents).
|
audit logging). See [Related documents](#related-documents).
|
||||||
|
|
||||||
> **New session? Call the guide tools first (#128).** Before using any other
|
> **New session? Call the guide tools first (#128 / #129).** Before using any other
|
||||||
> Gitea MCP tool in a fresh session, call `mcp_get_control_plane_guide`
|
> Gitea MCP tool in a fresh session, call `mcp_get_control_plane_guide`
|
||||||
> (read-only): it reports the active profile, authenticated identity,
|
> (read-only): it reports the active profile, authenticated identity,
|
||||||
> allowed/forbidden operations, profile-aware do/don't guidance, and the
|
> allowed/forbidden operations, profile-aware do/don't guidance, and the
|
||||||
> non-negotiable rules (hard stops, fail-closed behavior, head-SHA pinning,
|
> non-negotiable rules (hard stops, fail-closed behavior, head-SHA pinning,
|
||||||
> merge confirmation, redaction, author/reviewer separation, profile
|
> merge confirmation, redaction, author/reviewer separation, profile
|
||||||
> switching). Then call `mcp_list_project_skills` to discover the available
|
> switching). Also call `gitea_get_runtime_context` and `mcp_list_project_skills`
|
||||||
> project workflows and `mcp_get_skill_guide(<name>)` for step-by-step
|
> to discover the available project workflows and `mcp_get_skill_guide(<name>)`
|
||||||
> instructions. This replaces long pasted operator prompts for the standard
|
> for step-by-step instructions. This replaces long pasted operator prompts for
|
||||||
> rules; operator prompts still control task-specific scope.
|
> the standard rules; operator prompts still control task-specific scope.
|
||||||
|
> See issue #129 for the skill registry design.
|
||||||
|
|
||||||
For cross-project use, copy the portable workflow skill at
|
For cross-project use, copy the portable workflow skill at
|
||||||
[`../skills/llm-project-workflow/SKILL.md`](../skills/llm-project-workflow/SKILL.md).
|
[`../skills/llm-project-workflow/SKILL.md`](../skills/llm-project-workflow/SKILL.md).
|
||||||
|
|||||||
@@ -21,6 +21,18 @@
|
|||||||
"default_owner": "Contractor",
|
"default_owner": "Contractor",
|
||||||
"execution_profile": "mdcps"
|
"execution_profile": "mdcps"
|
||||||
},
|
},
|
||||||
|
"mdcps-reviewer": {
|
||||||
|
"base_url": "https://gitea.dadeschools.net",
|
||||||
|
"username": "913443",
|
||||||
|
"auth": {
|
||||||
|
"type": "keychain",
|
||||||
|
"id": "mdcps.gitea.reviewer.token"
|
||||||
|
},
|
||||||
|
"default_owner": "MDCPS",
|
||||||
|
"execution_profile": "mdcps-reviewer",
|
||||||
|
"allowed_operations": ["read", "review", "approve", "merge"],
|
||||||
|
"forbidden_operations": ["branch.push", "pr.create"]
|
||||||
|
},
|
||||||
"prgs-env": {
|
"prgs-env": {
|
||||||
"base_url": "https://gitea.prgs.cc",
|
"base_url": "https://gitea.prgs.cc",
|
||||||
"username": "jcwalker3",
|
"username": "jcwalker3",
|
||||||
|
|||||||
+11
-5
@@ -75,7 +75,7 @@ def v2_config():
|
|||||||
"identities": {
|
"identities": {
|
||||||
"author": {
|
"author": {
|
||||||
"role": "author",
|
"role": "author",
|
||||||
"username": "913443",
|
"username": "jcwalker3",
|
||||||
"auth": {"type": "keychain",
|
"auth": {"type": "keychain",
|
||||||
"id": "mdcps.gitea.author.token"},
|
"id": "mdcps.gitea.author.token"},
|
||||||
"allowed_operations": ["gitea.read"],
|
"allowed_operations": ["gitea.read"],
|
||||||
@@ -85,7 +85,7 @@ def v2_config():
|
|||||||
},
|
},
|
||||||
"reviewer": {
|
"reviewer": {
|
||||||
"role": "reviewer",
|
"role": "reviewer",
|
||||||
"username": "TBD-second-mdcps-user",
|
"username": "913443",
|
||||||
"auth": {"type": "keychain",
|
"auth": {"type": "keychain",
|
||||||
"id": "mdcps.gitea.reviewer.token"},
|
"id": "mdcps.gitea.reviewer.token"},
|
||||||
"allowed_operations": [
|
"allowed_operations": [
|
||||||
@@ -251,16 +251,22 @@ class TestV2Selectors(_V2Base):
|
|||||||
self._load_raises(mutate, "unknown profile")
|
self._load_raises(mutate, "unknown profile")
|
||||||
|
|
||||||
def test_tbd_username_fails_closed_on_selection(self):
|
def test_tbd_username_fails_closed_on_selection(self):
|
||||||
|
def mutate(cfg):
|
||||||
|
cfg["environments"]["mdcps"]["services"]["gitea"]["identities"]["reviewer"]["username"] = "TBD-second-mdcps-user"
|
||||||
|
cfg = v2_config()
|
||||||
|
mutate(cfg)
|
||||||
|
self._write(cfg)
|
||||||
|
with patch.dict(os.environ, self._env("mdcps.gitea.reviewer"), clear=True):
|
||||||
with self.assertRaises(gitea_config.ConfigError) as ctx:
|
with self.assertRaises(gitea_config.ConfigError) as ctx:
|
||||||
self._resolve("mdcps.gitea.reviewer")
|
gitea_config.resolve_profile()
|
||||||
msg = str(ctx.exception)
|
msg = str(ctx.exception)
|
||||||
self.assertIn("TBD", msg)
|
self.assertIn("TBD", msg)
|
||||||
self.assertIn("provision", msg)
|
# Note: after #107 provisioning, real username "913443" is used in live config and happy-path tests.
|
||||||
|
|
||||||
def test_tbd_identity_does_not_block_other_identities(self):
|
def test_tbd_identity_does_not_block_other_identities(self):
|
||||||
# Same file contains the TBD reviewer; author still resolves.
|
# Same file contains the TBD reviewer; author still resolves.
|
||||||
p = self._resolve("mdcps.gitea.author")
|
p = self._resolve("mdcps.gitea.author")
|
||||||
self.assertEqual(p["username"], "913443")
|
self.assertEqual(p["username"], "jcwalker3")
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -141,6 +141,20 @@ class TestControlPlaneGuide(GuideTestBase):
|
|||||||
with self.assertRaises(ValueError):
|
with self.assertRaises(ValueError):
|
||||||
mcp_get_control_plane_guide(remote="nope")
|
mcp_get_control_plane_guide(remote="nope")
|
||||||
|
|
||||||
|
@patch("mcp_server.api_request", return_value={"login": "new-session-bot"})
|
||||||
|
@patch("mcp_server.get_auth_header", return_value=FAKE_AUTH)
|
||||||
|
def test_new_session_can_call_guide_for_operating_model(self, _auth, _api):
|
||||||
|
"""Covers #129 AC: New LLM sessions can call one guide tool to understand the MCP Control Plane operating model."""
|
||||||
|
with patch.dict(os.environ, AUTHOR_ENV, clear=True):
|
||||||
|
g = mcp_get_control_plane_guide(remote="prgs")
|
||||||
|
self.assertTrue(g["read_only"])
|
||||||
|
self.assertIn("profile", g)
|
||||||
|
self.assertIn("identity", g)
|
||||||
|
self.assertIn("guidance", g)
|
||||||
|
self.assertIn("rules", g)
|
||||||
|
self.assertIn("workflows", g)
|
||||||
|
self.assertEqual(g["skills_tool"], "mcp_list_project_skills")
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# mcp_list_project_skills
|
# mcp_list_project_skills
|
||||||
|
|||||||
Reference in New Issue
Block a user