Migrate all repos into monorepo context folders
Bahn: aisupport, Analyse-O2C-C2S, awesome-bahn-mcp-servers, beam-mcp,
Confluence_Bot, db-planet-mcp-server, O2C-Harness, project-audit,
Projekt-KIQ-HP, teamlandkarte-mcp
Dhive: Jury-Voting
Privat: CV, NoteGraph (NOTE: NoteGraph needs complete redo after consolidation)
Shared: AI-Orchestrator, OrgMyLife, power_skills_and_more
Shared/references: symphony (read-only)
Bahn repos remain available as independent remotes - this monorepo
pulls them in via subtree, the originals are untouched.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: capacity-browsing
|
||||
description: >
|
||||
Browse free capacities and find matching tasks for a specific capacity.
|
||||
Use this skill when the user wants to see available people, inspect a
|
||||
capacity's details, or find tasks that match a person's profile.
|
||||
---
|
||||
|
||||
# Capacity Browsing & Task Matching
|
||||
|
||||
## Available Operations
|
||||
|
||||
### List free capacities
|
||||
Call `list_free_capacities(limit=20)` to show recent free capacities with capacity_id, role, and availability dates.
|
||||
|
||||
### View capacity details
|
||||
Call `get_capacity_details(capacity_id)` to inspect a specific capacity (role, competences, availability window, description, references, and certifications).
|
||||
|
||||
### Find matching tasks for a capacity
|
||||
Call `find_matching_tasks(capacity_id)` to find open tasks that match a person's profile.
|
||||
|
||||
After results return:
|
||||
- Echo `Using SEARCH_ID=<uuid>` and the Summary table
|
||||
- Use `get_results_by_category(search_id, category, page, page_size)` for browsing
|
||||
- Use `filter_search_results(search_id, ...)` for refinement
|
||||
- Task-search supports: `task_text_filter`, `task_competence_filter`
|
||||
|
||||
## Typical Flow
|
||||
|
||||
1. User asks to see available people → `list_free_capacities()`
|
||||
2. User picks a capacity → `get_capacity_details(capacity_id)`
|
||||
3. User wants matching tasks → `find_matching_tasks(capacity_id)`
|
||||
4. Browse/filter results as needed
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: capacity-matching
|
||||
description: >
|
||||
Find matching capacities for a task using the Teamlandkarte MCP server.
|
||||
Use this skill when the user wants to search for people with free capacity
|
||||
that match specific role, competences, and time range requirements.
|
||||
---
|
||||
|
||||
# Capacity Matching Workflow
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Before running a capacity search, you MUST have all of these:
|
||||
- **role_name**: The required role (or "Beliebige Rolle" if user refuses to specify)
|
||||
- **competences**: A non-empty list of required skills/technologies
|
||||
- **date_start / date_end**: A time range (open-ended allowed)
|
||||
- **description**: A concrete topic/goal (not just a single skill name)
|
||||
|
||||
## Decision: Extract vs Guided Capture
|
||||
|
||||
Use `extract_requirements(task_description)` when the user provides a reasonably complete description containing:
|
||||
- A scope/goal
|
||||
- At least 2 competences
|
||||
- A time range
|
||||
|
||||
Use **guided capture** when any of the above are missing:
|
||||
1. `start_guided_capture()`
|
||||
2. `guided_set_description(description)`
|
||||
3. `guided_set_role(role_name)`
|
||||
4. `guided_set_time_range(date_start?, date_end?)`
|
||||
5. `guided_set_competences([...])`
|
||||
|
||||
## Confirmation Gate (mandatory)
|
||||
|
||||
After requirements are captured:
|
||||
1. Call `show_pending_requirements()` to display the review table
|
||||
2. Ask: "Soll ich diese Anforderungen so übernehmen und die Suche starten?" (Ja/Nein)
|
||||
3. Only on "Ja": call `confirm_requirements(confirm=true)`
|
||||
4. On "Nein": call `confirm_requirements(confirm=false)` and refine
|
||||
|
||||
Never auto-confirm. Never confirm in the same turn as capture.
|
||||
|
||||
## Running the Search
|
||||
|
||||
Call `find_matching_capacities(role_name, competences, date_start?, date_end?)`.
|
||||
|
||||
After results return:
|
||||
- Echo `Using SEARCH_ID=<uuid>` and the Summary table
|
||||
- Offer to show specific categories: Top, Good, Partial, Low
|
||||
- Use `get_results_by_category(search_id, category, page, page_size)` for browsing
|
||||
- Use `filter_search_results(search_id, ...)` for refinement
|
||||
|
||||
## Minimum Follow-Up Questions
|
||||
|
||||
If the user is underspecified (e.g. "Ich suche jemanden mit JavaScript"), ask:
|
||||
1. Welche Rolle soll die Person haben?
|
||||
2. Ab wann und bis wann wird die Person benötigt?
|
||||
3. Welche weiteren wichtigen Skills sind relevant?
|
||||
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: requirement-capture
|
||||
description: >
|
||||
Capture and manage matching requirements for capacity searches.
|
||||
Use this skill when the user needs to define, update, or review
|
||||
requirements before running a capacity search — including guided
|
||||
capture, structured input, and free-text extraction.
|
||||
---
|
||||
|
||||
# Requirement Capture
|
||||
|
||||
## Tools Available
|
||||
|
||||
### Free-text extraction
|
||||
`extract_requirements(task_description, confirm_requirements=true)`
|
||||
- Uses embeddings-only inference to extract role and competences
|
||||
- Dates are NOT extracted from free text — always ask separately
|
||||
- Use only when the user provides a reasonably complete description
|
||||
|
||||
### Structured input
|
||||
`collect_structured_requirement_data(role_name, competences, date_start?, date_end?, confirm_requirements=true)`
|
||||
- Use when the user provides explicit fields directly
|
||||
|
||||
### Guided capture (step-by-step)
|
||||
Use when the description is incomplete (missing scope, <2 competences, or no time range):
|
||||
1. `start_guided_capture()`
|
||||
2. `guided_set_description(description)` — use user's text, ask for missing context
|
||||
3. `guided_set_role(role_name)`
|
||||
4. `guided_set_time_range(date_start?, date_end?)` — open-ended allowed
|
||||
5. `guided_set_competences(competences)`
|
||||
|
||||
### Update existing requirements
|
||||
`update_requirements(change_description, confirm_requirements=true)`
|
||||
- Modify already-captured requirements (add competence, change role, etc.)
|
||||
- Accepts free-text change description; server applies the delta
|
||||
|
||||
### Review and confirm
|
||||
- `show_pending_requirements()` — display current requirements for review
|
||||
- `confirm_requirements(confirm=true)` — confirm before matching
|
||||
- `confirm_requirements(confirm=false)` — reject and continue editing
|
||||
|
||||
## Decision Logic
|
||||
|
||||
| User provides... | Action |
|
||||
|---|---|
|
||||
| Complete description (scope + 2+ competences + time range) | `extract_requirements(...)` |
|
||||
| Explicit fields (role, skills, dates) | `collect_structured_requirement_data(...)` |
|
||||
| Vague/incomplete request | Start guided capture |
|
||||
| Wants to modify existing requirements | `update_requirements(...)` |
|
||||
|
||||
## Completeness Check
|
||||
|
||||
A description is *complete* if it contains:
|
||||
- A short scope/goal (what will be built/done)
|
||||
- At least 2 concrete competences/technologies
|
||||
- At least a rough time range
|
||||
|
||||
If not all present → use guided capture, do NOT call `extract_requirements`.
|
||||
@@ -0,0 +1,73 @@
|
||||
---
|
||||
name: scoring-interpretation
|
||||
description: >
|
||||
Interpret and explain matching scores from capacity and task searches.
|
||||
Use this skill when the user asks why a result scored high or low,
|
||||
what the scores mean, or how to improve matching results.
|
||||
---
|
||||
|
||||
# Scoring Interpretation
|
||||
|
||||
## Score Components
|
||||
|
||||
Every matching result has three scores:
|
||||
- **Role Score** (0.0–1.0): Cosine similarity between required role and candidate's role embedding
|
||||
- **Competence Score** (0.0–1.0): Aggregated similarity across all required competences
|
||||
- **Overall Score**: `role_weight × role_score + competence_weight × competence_score`
|
||||
|
||||
Weights are configured in `config.toml` under `[matching]`.
|
||||
|
||||
## Result Categories
|
||||
|
||||
Results are grouped by overall score into:
|
||||
- **Top**: Highest scoring matches
|
||||
- **Good**: Strong matches
|
||||
- **Partial**: Some overlap but gaps
|
||||
- **Low**: Weak matches
|
||||
- **Irrelevant**: Very low or no meaningful overlap
|
||||
|
||||
Thresholds are configurable via `matching.category_thresholds`.
|
||||
|
||||
## Availability
|
||||
|
||||
Availability is shown as **overlap percentage** against the provided date range:
|
||||
- 100% = candidate fully covers the requested period
|
||||
- <100% = partial overlap
|
||||
- `is_fully_available=true` filter excludes partial matches
|
||||
|
||||
## Embedding Mode (default)
|
||||
|
||||
- Cosine similarity between embedding vectors
|
||||
- Semantic: "ML" and "Machine Learning" will have high similarity
|
||||
- Range: 0.0 (unrelated) to 1.0 (identical meaning)
|
||||
|
||||
## BM25 + RRF Mode (`use_bm25_search = true`)
|
||||
|
||||
- Lexical token matching, NOT semantic
|
||||
- Score of 0.0 = no shared tokens (not a semantic distance)
|
||||
- "Python" matches "Python" perfectly
|
||||
- "ML" does NOT match "Machine Learning" (no shared tokens)
|
||||
- Eliminates false positives but may miss valid synonyms
|
||||
|
||||
### With Auto-Tagging (`use_auto_tagging = true`)
|
||||
|
||||
- LLM expands candidate competences with canonical equivalents
|
||||
- "ML" → "Machine Learning" expansion happens before BM25 scoring
|
||||
- Positive scores may reflect LLM-inferred equivalence
|
||||
- If LLM fails, scoring continues on unexpanded list (no failure)
|
||||
|
||||
## Common Questions
|
||||
|
||||
**"Why did this person score 0.0 on competences?"**
|
||||
- BM25 mode: no lexical overlap between required and candidate competences
|
||||
- Embedding mode: very different semantic meaning (rare for 0.0)
|
||||
|
||||
**"Why is a good match ranked Low?"**
|
||||
- Check if role mismatch is dragging down overall score
|
||||
- Check weights: high role_weight penalizes role mismatches heavily
|
||||
|
||||
**"How to get better results?"**
|
||||
- Add more specific competences
|
||||
- Use canonical terms (full names, not abbreviations in BM25 mode)
|
||||
- Broaden the time range if too restrictive
|
||||
- Consider enabling auto-tagging for synonym coverage
|
||||
@@ -0,0 +1,47 @@
|
||||
---
|
||||
name: search-refinement
|
||||
description: >
|
||||
Filter, paginate, and browse search results from capacity or task matching.
|
||||
Use this skill when the user wants to see different result categories,
|
||||
filter by availability, or page through results.
|
||||
---
|
||||
|
||||
# Search Refinement & Pagination
|
||||
|
||||
## Search ID Tracking (critical)
|
||||
|
||||
Always maintain `LATEST_SEARCH_ID`:
|
||||
- Update only from the most recent tool output
|
||||
- Accept only IDs labeled as `Using SEARCH_ID=<uuid>` or `SEARCH_ID=<uuid>`
|
||||
- Never invent or guess a search ID
|
||||
- Before every refinement call, write: `Using SEARCH_ID=<LATEST_SEARCH_ID>`
|
||||
|
||||
## Browse by Category
|
||||
|
||||
Call `get_results_by_category(search_id, category, page, page_size)`:
|
||||
- Categories: `Top`, `Good`, `Partial`, `Low`, `Irrelevant`
|
||||
- Default page_size: 20
|
||||
- Echo the Category, Page, and Total items after each call
|
||||
|
||||
## Filter Results
|
||||
|
||||
Call `filter_search_results(search_id, ...)` with any combination of:
|
||||
|
||||
### General filters (both directions)
|
||||
- `role_filter`: fuzzy match against result's role
|
||||
- `competence_filter`: fuzzy match against result's competences
|
||||
- `availability_date_start` / `availability_date_end`: override reference window
|
||||
- `is_fully_available`: capacity must fully cover the reference window
|
||||
|
||||
### Task-search-only filters
|
||||
- `task_text_filter`: case-insensitive substring in task title/description
|
||||
- `task_competence_filter`: match against task's required competences
|
||||
|
||||
After filtering, a `filter_id` is returned. Use it in subsequent `get_results_by_category` calls.
|
||||
|
||||
## Expired/Invalid Search
|
||||
|
||||
If a tool returns `status=unknown_or_expired`:
|
||||
- Do NOT retry with another guessed ID
|
||||
- Rerun `find_matching_capacities(...)` or `find_matching_tasks(...)` to create a fresh search
|
||||
- Replace `LATEST_SEARCH_ID` with the new value
|
||||
@@ -0,0 +1,33 @@
|
||||
---
|
||||
name: task-discovery
|
||||
description: >
|
||||
Browse and inspect published tasks from the Teamlandkarte database.
|
||||
Use this skill when the user wants to list open tasks, view task details,
|
||||
validate task requirements, or infer the primary role for a task.
|
||||
---
|
||||
|
||||
# Task Discovery
|
||||
|
||||
## Available Operations
|
||||
|
||||
### List open tasks
|
||||
Call `list_open_tasks(limit=20)` to show a table of published tasks with task_id, title, created date, and time range.
|
||||
|
||||
### View task details
|
||||
Call `get_task_details(task_id)` to inspect a specific task's fields (title, description, skills, time range).
|
||||
|
||||
### Validate task requirements
|
||||
Call `validate_task_requirements(task_id)` to compare DB-stored skills vs embedding-inferred skills.
|
||||
- Only use when the user explicitly asks for validation
|
||||
- This is NOT part of the default matching workflow
|
||||
|
||||
### Infer primary role
|
||||
Call `infer_primary_role(task_id=...)` or `infer_primary_role(task_text=...)` to suggest the closest matching role.
|
||||
- Use when the role is unclear before starting a capacity search
|
||||
|
||||
## Typical Flow
|
||||
|
||||
1. User asks to see tasks → `list_open_tasks()`
|
||||
2. User picks a task → `get_task_details(task_id)`
|
||||
3. Optionally validate → `validate_task_requirements(task_id)`
|
||||
4. Proceed to capacity matching (use the capacity-matching skill)
|
||||
Reference in New Issue
Block a user