{"id":50974338,"url":"https://github.com/broomva/role-x","last_synced_at":"2026-06-19T06:01:52.963Z","repository":{"id":357837061,"uuid":"1238157305","full_name":"broomva/role-x","owner":"broomva","description":"bstack P17 — Lens-Routed Request Articulation: the typed routing layer above P5 parallel-agent dispatch. Substantive context grounding, no 'act as X' persona theater.","archived":false,"fork":false,"pushed_at":"2026-06-01T21:27:31.000Z","size":137,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-01T23:15:44.423Z","etag":null,"topics":["agent-skills","bstack","bstack-primitive","claude-code","context-engineering","prompt-engineering","python","reasoning-network","skills"],"latest_commit_sha":null,"homepage":"https://broomva.tech/skills","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/broomva.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-13T21:41:05.000Z","updated_at":"2026-06-01T21:27:34.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/broomva/role-x","commit_stats":null,"previous_names":["broomva/role-x"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/broomva/role-x","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/broomva%2Frole-x","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/broomva%2Frole-x/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/broomva%2Frole-x/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/broomva%2Frole-x/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/broomva","download_url":"https://codeload.github.com/broomva/role-x/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/broomva%2Frole-x/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34519051,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["agent-skills","bstack","bstack-primitive","claude-code","context-engineering","prompt-engineering","python","reasoning-network","skills"],"created_at":"2026-06-19T06:01:51.959Z","updated_at":"2026-06-19T06:01:52.951Z","avatar_url":"https://github.com/broomva.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# role-x — bstack P17: Lens-Routed Request Articulation\n\n\u003e **The typed routing layer above P5 parallel-agent dispatch.** On every substantive user input, the first-touch agent reflexively selects a domain lens, loads its substantive context, and decides single-agent vs surfaced rewrite vs parallel-team plan. No \"act as X\" persona theater — substantive context grounding only.\n\n[![CI](https://github.com/broomva/role-x/actions/workflows/test.yml/badge.svg)](https://github.com/broomva/role-x/actions/workflows/test.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![skills.sh](https://img.shields.io/badge/install-npx%20skills%20add%20broomva%2Frole--x-blue)](https://skills.sh)\n\n## Why role-x exists\n\nModern frontier-model evidence ([PRISM USC 2026](https://arxiv.org/html/2603.18507v1), [Zheng et al. arXiv 2311.10054](https://arxiv.org/html/2311.10054v3), [Anthropic best-practices](https://claude.com/blog/best-practices-for-prompt-engineering)) shows that naive \"act as expert X\" persona prompting **hurts** code/factual accuracy — MMLU drops 71.6% → 66.3% with long expert personas; \"no or small negative effects\" across 162 personas × 4 LLMs × 2410 questions. Telling a model it's an expert does not impart expertise.\n\nWhat *does* work is **substantive context grounding**: concrete files, conventions, prior decisions, domain-specific checklists. `role-x` makes that grounding **addressable, composable, and self-improving** via a Markdown lens registry the agent reasons over before responding.\n\n## What role-x is\n\nA bstack P17 skill providing:\n\n1. **Lens registry** — `roles/_meta.md` (always-loaded base) + `roles/\u003cname\u003e.md` per-domain lenses. Each lens has YAML frontmatter (signals, context_loaders, quality_bar, prompt_improvement_patterns, mode_escalation, out_of_scope) and a prose body.\n2. **Three modes per request** — `augment` (silent context load, default) / `rewrite` (surfaced prompt refinement, user accepts) / `decompose` (parallel-agent plan via P5, user-approved).\n3. **CLI helpers** (this repo's `scripts/role-x.py`):\n   - `role-x list` — list all lenses in `roles/`\n   - `role-x validate \u003cpath\u003e` — validate lens YAML frontmatter against schema\n   - `role-x index` — regenerate `roles/_index.md` discovery file\n4. **Reference docs** — schema, selection algorithm, mode-decision tree, feedback loop (M2+).\n\n## Quick start\n\n```bash\n# 1. Install via skills.sh\nnpx skills add broomva/role-x\n\n# 2. Create a lens registry in your workspace\nmkdir -p roles\n# Author roles/_meta.md (always-loaded base) and per-domain lenses\n\n# 3. Validate a lens against the schema\npython3 ~/.agents/skills/role-x/scripts/role-x.py validate roles/_meta.md\n# → OK: roles/_meta.md is a valid lens\n\n# 4. List all lenses\npython3 ~/.agents/skills/role-x/scripts/role-x.py list --roles-dir roles\n\n# 5. Regenerate the discovery index\npython3 ~/.agents/skills/role-x/scripts/role-x.py index --roles-dir roles\n# → wrote roles/_index.md (N lenses)\n```\n\n## How the agent uses role-x\n\nAt UserPromptSubmit for substantive work, the agent reasons through:\n\n```\n1. Snapshot signals (P15)\n   - current branch (git rev-parse --abbrev-ref HEAD)\n   - touched files (git diff --name-only)\n   - prompt keywords\n   - Linear ticket labels\n\n2. Score lens registry\n   For each roles/\u003cname\u003e.md:\n     score = matches in {paths, prompt_keywords, branch_patterns, linear_labels}\n   Threshold: score ≥ 2\n\n3. Resolve extends: chain\n   Walk back to _meta; merge context_loaders + quality_bar + prompt_improvement_patterns\n\n4. Decide mode\n   augment | rewrite | decompose\n   per lens default_mode + mode_escalation\n\n5. Surface to user (unless augment)\n   \"Applying lens(es) X, Y because [signals]. Suggestions: …. Proceeding.\"\n\n6. Emit event to ~/.config/broomva/role/events.jsonl  (M2 — hook-driven)\n```\n\nSelection and mode-decision are **reasoning-enforced** (bstack-idiom, same as P10/P14/P15/P16). The CLI validates lens schemas and generates the discovery index; it does **not** run selection at runtime.\n\n## Subcommands\n\n| Command | Purpose |\n|---|---|\n| `role-x list [--roles-dir roles]` | List all lenses with status + extends + default_mode |\n| `role-x validate \u003cpath\u003e` | Validate a lens markdown file against the schema (frontmatter shape, required fields, enum values, name-matches-filename) |\n| `role-x index [--roles-dir roles]` | Regenerate `roles/_index.md` discovery file |\n| `role-x intake [--prompt … --workspace … --session …]` | **v0.2.0+** — `UserPromptSubmit` hook entry point. Scores lenses against current signals (git + prompt content), walks `extends:` chain, decides mode, emits event to `~/.config/broomva/role/events.jsonl`, prints agent-context to stdout. Reads JSON from stdin if `--prompt` omitted (the Claude Code hook protocol). |\n| `role-x suggest [--since 7d --threshold N --limit M --events-path PATH]` | **v0.4.0+** — analyze `events.jsonl` over a window. Reports fire-rate (lens-fired vs `_meta`-only), per-lens drift (fires + sessions + avg prompt length), and (when sanitized capture is on) emergent keyword clusters in unrouted events with suggested lens names. Read-only. |\n| `role-x init \u003cname\u003e [--keywords K1,K2 --paths P1,P2 --threshold N --extends NAME ...]` | **v0.4.0+** — scaffold a new `status: candidate` lens under `roles/\u003cname\u003e.md` from CLI flags. Scaffolded file passes `validate` immediately. Author edits, then promotes to `status: active` after ≥3 positive-outcome uses (P16). |\n| `role-x coverage [--since 7d --min-events 10 --force]` | **v0.4.1+** — brief registry-health summary. Silent (exit 0, no output) when fire-rate ≥30% AND sanitized capture is on. Surfaces a 3-5 line nudge otherwise. Designed as the entry point for the `SessionStart` hook with a 24h cooldown — `scripts/role-x-coverage-hook.sh` wires this. |\n\n## Hook integration (v0.2.0+)\n\nThe `intake` subcommand can fire automatically on every substantive user prompt via a Claude Code `UserPromptSubmit` hook. Add to your workspace's `.claude/settings.json`:\n\n```json\n{\n  \"hooks\": {\n    \"UserPromptSubmit\": [\n      {\n        \"hooks\": [\n          {\n            \"type\": \"command\",\n            \"command\": \"$HOME/.agents/skills/role-x/scripts/role-x-intake-hook.sh\",\n            \"timeout\": 5\n          }\n        ]\n      }\n    ]\n  }\n}\n```\n\nThe hook:\n\n- Reads the prompt JSON payload from stdin\n- Resolves workspace via `$CLAUDE_PROJECT_DIR` (or `$PWD`)\n- Scores `roles/*.md` against signals (git branch, touched files, prompt keywords)\n- Selects lens(es) with score ≥2, walks `extends:` chain to `_meta`\n- Decides mode (`augment` / `rewrite` / `decompose`)\n- Appends a structured event to `~/.config/broomva/role/events.jsonl`\n- Prints the lens metadata + composed `quality_bar` + suggestions to stdout (added to the agent's working context)\n\n**Always exits 0.** Graceful-fails if PyYAML is missing, the workspace has no `roles/` directory, or the prompt is shorter than 3 words (carve-out for trivial prompts).\n\n### Test the hook locally\n\n```bash\necho '{\"prompt\": \"implement rust cargo tokio async support\", \"session_id\": \"manual\"}' \\\n  | CLAUDE_PROJECT_DIR=$PWD ~/.agents/skills/role-x/scripts/role-x-intake-hook.sh\n```\n\nExpected output: lens selected, mode decided, quality_bar surfaced, any `context_loaders.entities` core_claim constraints surfaced, event appended to events.jsonl.\n\n### Event schema\n\n```json\n{\n  \"ts\": \"\u003cISO-8601 UTC\u003e\",\n  \"event\": \"intake\",\n  \"session\": \"\u003csession id\u003e\",\n  \"prompt_digest\": \"sha256:\u003chex\u003e\",\n  \"prompt_word_count\": 42,\n  \"lenses_selected\": [\"rust-systems\"],\n  \"lenses_extended\": [\"rust-systems\", \"_meta\"],\n  \"mode\": \"augment\",\n  \"mode_escalation_reason\": null,\n  \"signals_matched\": {\"paths\": 0, \"prompt_keywords\": 4, \"branch_patterns\": 0, \"linear_labels\": 0}\n}\n```\n\nSee [`references/feedback-loop.md`](references/feedback-loop.md) for the full design (M4 dream cycle consumes this telemetry).\n\n## Lens schema (minimal example)\n\n```yaml\n---\nname: rust-systems\nstatus: active\nextends: _meta\nsignals:\n  paths: [\"**/Cargo.toml\", \"**/*.rs\"]\n  prompt_keywords: [\"rust\", \"cargo\", \"tokio\", \"MSRV\"]\n  branch_patterns: [\"feat/rust-*\"]\n  linear_labels: [\"lang:rust\"]\ncontext_loaders:\n  files: [\"AGENTS.md#Conventions\", \"core/life/CLAUDE.md\"]\n  entities: [\"research/entities/concept/stability-budget.md\"]\n  skills: [\"rust-best-practices\"]\n  glob_hints: [\"core/life/rust-toolchain.toml\"]\ndefault_mode: augment\nquality_bar:\n  - \"MSRV declared in Cargo.toml is honored (workspace default: 1.85)\"\n  - \"Edition 2024 idioms used\"\n  - \"No unwrap() in non-test code unless documented\"\nprompt_improvement_patterns:\n  - signal: \"no MSRV mentioned\"\n    suggestion: \"Specify target MSRV\"\nmode_escalation:\n  rewrite_when: [\"prompt asks for new API without naming trait shape\"]\n  decompose_when: [\"prompt spans ≥2 crates with no shared types\"]\nout_of_scope: [\"Non-Rust files\"]\nrelated_lenses: [\"api-design\", \"security-review\"]\ncreated: 2026-05-13\nupdated: 2026-05-13\n---\n# rust-systems lens\n[Body: prose detail, anti-patterns, composition triggers]\n```\n\nFull schema reference: [`references/lens-schema.md`](references/lens-schema.md).\n\n## Cardinal invariant\n\n\u003e **No `act as X` persona rewrites.** Lenses load substantive context (files, conventions, checklists, optional suggestions). They do *not* insert persona declarations into the model's working context. The 2026 research is clear: persona declarations don't add expertise and frequently hurt accuracy.\n\n## Where role-x fits in the bstack\n\n```\nUser intent → P17 role-x intake → P15 state snapshot → Linear (P3) → Agent (P5)\n                ↓ typed edges (lens per fan-out)\n              P5 parallel dispatch becomes a typed graph\n                ↓ lens.quality_bar IS the P14 dep-chain template\n              P14 enumeration is domain-specific\n                ↓ events.jsonl (M2)\n              P13 dream cycle consolidates lens rules (M4)\n                ↓ per-lens rule-of-three\n              P16 promotes candidate lenses to status: active\n```\n\n`role-x` composes with — does not duplicate — existing primitives. See [`broomva/workspace`](https://github.com/broomva/workspace) `AGENTS.md` §P17 for the full reflexive trigger rule.\n\n## Tests\n\n```bash\npython3 -m venv .venv \u0026\u0026 source .venv/bin/activate\npip install -r tests/requirements-dev.txt\npython3 -m pytest tests/ -v\n```\n\n## Spec \u0026 design\n\nFull design lives at [`broomva/workspace`](https://github.com/broomva/workspace) under `docs/superpowers/specs/2026-05-13-role-x-primitive-design.md` (570 lines) and the implementation plan at `docs/superpowers/plans/2026-05-13-role-x-primitive-implementation.md` (2068 lines).\n\n## Observability + lens authoring (v0.4.0+)\n\nThe system is designed to grow organically — the `roles/` registry expands from real telemetry, not speculative authoring. The pipeline:\n\n1. **Capture** (v0.2.0+) — `intake` hook logs every prompt routing decision to `~/.config/broomva/role/events.jsonl`\n2. **Sanitize** (v0.4.0, opt-in) — optionally extract top-N keywords or first-N chars from prompts for downstream clustering\n3. **Analyze** (v0.4.0) — `role-x suggest` reports fire-rate, per-lens drift, and emergent keyword clusters\n4. **Scaffold** (v0.4.0) — `role-x init \u003cname\u003e` generates a candidate lens from CLI flags\n5. **Promote** (P16) — after ≥3 positive-outcome uses, author updates `status: candidate → active`\n6. **Tune** (v0.5.0, planned) — `role-x tune \u003clens\u003e` proposes keyword/threshold/weight diffs as a PR\n7. **Replay** (v0.6.0, planned) — full P13 dream cycle: `role-x-replay.py` consolidates lens rule updates from outcome data\n\n**Privacy by default**: sanitized prompt capture is **off** unless you write\n`~/.config/broomva/role/config.json` with `{\"capture_sanitized_prompt\": true}`. Without\nthat file, only `prompt_digest` (sha256) is recorded — same as v0.1.0-v0.3.0.\n\nExample workflow (after a week of telemetry):\n\n```bash\n# 1. Turn on sanitized capture\ncat \u003e ~/.config/broomva/role/config.json \u003c\u003cEOF\n{\"capture_sanitized_prompt\": true, \"sanitization_strategy\": \"keywords\", \"sanitization_top_n_keywords\": 5}\nEOF\n\n# 2. Let the hook accumulate events for a few days\n\n# 3. See what lenses to author\nrole-x suggest --since 7d\n\n# 4. Scaffold the top suggestion\nrole-x init deploy-vercel-env --keywords \"deploy,vercel,env,preview\" --paths \"**/vercel.json\"\n\n# 5. Edit the TODO sections, validate, commit\nrole-x validate roles/deploy-vercel-env.md\nrole-x index --roles-dir roles\ngit add roles/ \u0026\u0026 git commit -m \"feat(roles): add deploy-vercel-env candidate lens\"\n```\n\n## Roadmap\n\n- **v0.1.0** — Markdown lens registry + CLI (`validate`, `list`, `index`) + reference docs\n- **v0.2.0** — `intake` subcommand + `UserPromptSubmit` hook + `~/.config/broomva/role/events.jsonl` capture\n- **v0.3.0** — Per-lens `threshold:` override + per-signal-type `signals.weights:`\n- **v0.4.0** — Observability for organic growth: `role-x suggest` + `role-x init` + opt-in sanitized prompt capture\n- **v0.4.1** (this release) — Meta-progression nudges: `role-x coverage` SessionStart hook + per-prompt authoring suggestion when intake routes to `_meta` only on a domain-rich prompt\n- **v0.5.0** — `role-x tune \u003clens\u003e` + `role-x propose-lens \u003ccluster\u003e` (PR-driven lens updates)\n- **v0.6.0** — P13 dream cycle: `role-x-replay.py` with replay-against-frozen-substrate; `status.json` per-lens stats cache; auto-promote candidates on rule-of-three positive outcomes\n- **v0.7.0** — `PostToolUse` + `Stop` outcome hooks → quality signals per lens-use\n- **v0.8.0** — Lens decay + auto-demotion of unused lenses\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n## Related\n\n- [broomva/workspace](https://github.com/broomva/workspace) — unified workspace + governance (P17 §AGENTS.md, `roles/` registry)\n- [broomva/bstack](https://github.com/broomva/bstack) — bstack catalog skill (counts P1-P17)\n- [broomva/p9](https://github.com/broomva/p9) — bstack P7 (CI watcher + productive wait)\n- [broomva/persist](https://github.com/broomva/persist) — bstack P12 (cross-context restart loop)\n- [broomva/bookkeeping](https://github.com/broomva/bookkeeping) — bstack P6 (knowledge graph engine)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbroomva%2Frole-x","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbroomva%2Frole-x","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbroomva%2Frole-x/lists"}