Enhance MCP development features and introduce skills management

- Added configuration options for requiring human approval before applying LLM-generated MCP patches.
- Updated Docker setup to include skills directory.
- Integrated skills management into the backend, allowing for procedural guides and skill matching.
- Refactored database initialization to apply Alembic migrations.
- Enhanced task approval process to handle MCP patch applications with optional approval.
- Introduced new schemas for skills and updated existing APIs to support skills functionality.

This commit lays the groundwork for improved agent capabilities and better management of MCP development processes.
This commit is contained in:
2026-06-14 22:27:24 +03:00
parent 6185b9b85a
commit 0375b20bb4
30 changed files with 1733 additions and 151 deletions

View File

@@ -0,0 +1,71 @@
---
id: pfsense-change-safe
name: Safe pfSense changes
description: >-
Backup-before-change workflow, evidence capture, and approval gates for
production firewall/NAT edits on vessel pfSense instances.
priority: 80
rule_ids:
- one-way-audio
- no-registration
- list-firewall-rules
match:
keywords:
- firewall rule
- add rule
- change nat
- port forward
- snat
- outbound nat
- modify pfsense
- fix firewall
- blocked
- pass rule
all_of: []
---
# Safe pfSense changes on vessels
## Read before write (always)
1. List current state: interfaces, firewall rules, port forwards, outbound NAT.
2. Identify the **exact gap** with filter.log or rule tracker IDs — not theory.
3. Capture config backup or export before any write.
Agentic OS routes **config-changing fixes** through human approval. Proposed fixes with `is_config_change: true` appear in the task approval queue.
## Pre-change checklist
- [ ] Confirmed interface names live (`vtnet2` CREW, `vtnet3` Business, etc.)
- [ ] Identified associated NAT + filter rule pairs
- [ ] Documented evidence (filter.log line, blocked port/proto, source/dest)
- [ ] Backup taken or backup tool available
- [ ] Change is minimal — one rule/NAT entry, not broad "allow all"
## Common safe patterns (GeneseasX VoIP)
| Fix | Typical rule |
|-----|--------------|
| One-way audio | Pass UDP 10000-10029 phone VLAN → shipPortal |
| RTP SNAT | Outbound NAT for phone subnet RTP to segment VIP |
| SIP registration | Port-forward UDP 5060 + pass on phone VLAN |
## What NOT to do
- Do not disable pfSense entirely or add overly broad "any any" rules.
- Do not assume golden-lab IPs — confirm vessel inventory addresses.
- Do not list connect/diagnostic steps as `proposed_fixes` — those belong in `steps_taken`.
## Report expectations
When recommending a change:
- Describe **exact** rule (interface, proto, ports, source, dest)
- Reference evidence from diagnostics already collected
- Set `is_config_change: true` only for actual pfSense write operations
- Note if MCP writes require `PFSENSE_ALLOW_WRITES=true` on the MCP server
## Post-change verification
- Re-test the original symptom (registration, RTP counters, filter.log clean)
- Upsert a memory record with rule tracker IDs and outcome for future tasks

View File

@@ -0,0 +1,81 @@
---
id: vessel-dns-portal
name: Vessel DNS and captive portal
description: >-
Crew/business DNS slowness, ship-dns upstream timeouts, captive portal auth,
RADIUS, and hairpin portal access on GeneseasX stacks.
priority: 85
rule_ids:
- crew-dns-slow
- dns-captive-portal
match:
keywords:
- dns
- slow dns
- ship-dns
- captive
- portal
- crew
- radius
- coovachilli
- login
- internet
- redirect
- resolver
---
# Vessel DNS and captive portal
## Architecture (typical GeneseasX)
- **pfSense** is the DNS gateway for crew/business — redirects UDP/53 per segment.
- **Do NOT** hand crew/business the Docker VM IP (`10.20.30.222`) as DNS directly.
- **ship-dns** container on Docker VM resolves upstream; misconfigured primary = multi-second delays.
- **Captive portal** on CREW VLAN: pfSense CP + RADIUS back to Docker stack.
## Crew DNS slow (`ship-dns`)
**Known root cause:** primary upstream unreachable from Docker VM → every query waits full timeout before fallback.
| Symptom | Likely cause |
|---------|--------------|
| ~3s per lookup | Primary (e.g. `1.1.1.1`) blocked; fallback works after timeout |
| Fast after fix | Primary `8.8.8.8`, secondary `9.9.9.9`, `dns_timeout=2` |
**Investigation order:**
1. Docker VM: `docker ps` — ship-dns container healthy
2. Docker VM: time lookups per upstream (`dig @1.1.1.1`, `@8.8.8.8`, `@9.9.9.9`)
3. ship-dns config: primary/secondary/timeout, worker concurrency
4. pfSense: crew/business DNS redirect points at pfSense, not Docker IP
**Persistence warning:** in-place edits inside ship-dns container **revert on image recreate**. Fixes belong in the image/build, not only `docker cp`.
## Captive portal / crew internet
**Flow:** crew device → pfSense captive portal → RADIUS auth → Docker RADIUS/portal containers.
| Symptom | Check |
|---------|-------|
| Portal page won't load | Hairpin / NAT reflection: crew → pfSense:443 → Docker portal |
| Auth fails | RADIUS reachability (auth/acct ports) to Docker stack |
| Authenticated but no service | Missing pass rules on CREW for new services (e.g. VoIP added later) |
**Investigation order:**
1. pfSense: captive portal zone status, CREW floating + interface rules
2. pfSense: 443 portal redirect, NAT reflection, RADIUS pass rules to Docker
3. Docker VM: portal + RADIUS container health and logs on failed auth
## pfSense interface roles (confirm live)
- CREW (`vtnet2`): isolated, captive portal, floating rules
- Business (`vtnet3`): restrictive pass (DNS/HTTPS/SIP)
- Management (`vtnet4`): usually permissive
## Evidence to capture
- Per-upstream DNS timing from Docker VM
- ship-dns effective resolver settings
- pfSense CP + RADIUS rule list
- Portal/RADIUS container logs for failed login attempts

View File

@@ -0,0 +1,97 @@
---
id: vessel-voip
name: Vessel VoIP troubleshooting
description: >-
Deep procedural guide for GeneseasX VoIP — SIP registration, one-way audio,
RTP path, IAX trunks, and Asterisk NAT on ship stacks.
priority: 90
rule_ids:
- one-way-audio
- no-registration
- outbound-trunk-failure
- asterisk-health
match:
keywords:
- voip
- sip
- pjsip
- rtp
- registration
- one-way
- one way
- trunk
- iax
- dialplan
- codec
- yealink
- phone
- dial tone
- no audio
- asterisk
---
# Vessel VoIP stack
## Layer model (bottom → top)
| Layer | Component | Typical symptoms |
|-------|-----------|------------------|
| 1 | pfSense VM | Blocked SIP/RTP, wrong NAT, missing pass on phone VLAN |
| 2 | Docker VM (`shipPortal`) | Container down, wrong published ports |
| 3 | Asterisk container | Registration, SDP, codec, dialplan |
| 4 | Phones / FortiGate | Yealink NAT quirks, trunk via wrong gateway |
**Topology is vessel-specific.** Golden-lab reference (confirm live):
| Role | Typical IP / alias |
|------|---------------------|
| pfSense Management | `10.20.30.1` (`vtnet4`) |
| shipPortal / Docker VM | `10.20.30.222` |
| Business VLAN | `10.0.100.0/24` (`vtnet3`) |
| CREW VLAN | `192.168.100.0/24` (`vtnet2`) |
Interface map (verify on device): `vtnet0`=WAN1, `vtnet1`=WAN2, `vtnet2`=CREW, `vtnet3`=Business, `vtnet4`=Management.
## Symptom → start here
| Symptom | First layer | Then |
|---------|-------------|------|
| Phone won't register | pfSense — SIP NAT + pass rules on phone VLAN | Asterisk — `pjsip show registrations` |
| One-way audio | pfSense — UDP 10000-10029 pass toward shipPortal | Asterisk — `local_net`, `external_media_address` |
| Trunk / dial tone down | Asterisk — PJSIP/IAX peers | pfSense — outbound NAT if media leaves WAN |
| Codec mismatch | Asterisk — allowed codecs vs trunk | Not pfSense unless blocked |
## One-way audio playbook (proven order)
1. **Which direction is silent?** Remote can't hear phone → phone→Asterisk RTP likely blocked. Phone can't hear remote → Asterisk→phone or return path.
2. **pfSense filter.log** — blocked flows from phone to `shipPortal:100xx` on Business (`vtnet3`)?
3. **Pass rule**`pass udp` phone VLAN → shipPortal ports `10000-10029`.
4. **Outbound NAT** — RTP SNAT to correct segment IP (e.g. phone VLAN VIP `192.168.0.254`) when hairpin involved.
5. **Asterisk**`local_net` must include phone subnet AND VoIP subnet (`10.20.30.0/24`). `external_media_address` / `external_signaling_address` = reachable Asterisk IP.
6. **Live verify** — RTP RX/TX counters during call; both directions should increment.
## Registration playbook
- Phones typically register via **pfSense SIP NAT redirect** (e.g. `192.168.0.254:5060` → Asterisk), not directly to Asterisk IP in phone config.
- Yealink red flags: SIP server = pfSense VIP with NAT keepalive on but rport off.
- Asterisk: failing `qualify` on endpoint = path/NAT problem, not credentials.
- Check: port-forward UDP 5060, matching pass rule, `pjsip show registrations`, `pjsip show contacts`.
## Outbound trunk / IAX
- IAX2 uses UDP **4569** — confirm pfSense pass + outbound NAT if crossing WAN.
- Dialplan: `_7XXXX` patterns may strip prefix — verify dial string matches trunk expectation.
- Codec: trunk may require ulaw while endpoint negotiates opus — check `iax2 show peer` / PJSIP allow list.
- Congestion = route/codec/dialplan, not firewall, when peer shows OK but calls fail.
## Evidence to capture
- pfSense rule tracker IDs, filter.log lines for blocked RTP/SIP
- Asterisk CLI: endpoint config, channel stats, `core show channels`
- Do not propose firewall writes without backup — see pfsense-change-safe skill
## During investigation
- Read before write on pfSense.
- Cross-check NAT rules with their associated filter rules.
- Build on project memory hits — do not repeat ruled-out causes from prior tasks.