{"id":51879695,"url":"https://github.com/19pine-ai/principal-loyalty","last_synced_at":"2026-07-25T11:01:36.382Z","repository":{"id":368317043,"uuid":"1274992399","full_name":"19PINE-AI/principal-loyalty","owner":"19PINE-AI","description":"Whose Side Is Your Agent On? PrincipalBench — a multi-turn benchmark and post-training methods (prompt scaffold + per-token-KL distillation) for multi-party principal loyalty in LLM agents.","archived":false,"fork":false,"pushed_at":"2026-06-30T02:21:56.000Z","size":67147,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T04:11:13.146Z","etag":null,"topics":["agent-safety","ai-alignment","ai-safety","benchmark","knowledge-distillation","large-language-models","llm-agents","llm-evaluation","nlp","principal-agent","reinforcement-learning"],"latest_commit_sha":null,"homepage":"https://01.me/research/principal-loyalty","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/19PINE-AI.png","metadata":{"files":{"readme":"README.md","changelog":null,"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-06-20T05:49:03.000Z","updated_at":"2026-06-30T02:21:59.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/19PINE-AI/principal-loyalty","commit_stats":null,"previous_names":["19pine-ai/principal-loyalty"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/19PINE-AI/principal-loyalty","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/19PINE-AI%2Fprincipal-loyalty","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/19PINE-AI%2Fprincipal-loyalty/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/19PINE-AI%2Fprincipal-loyalty/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/19PINE-AI%2Fprincipal-loyalty/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/19PINE-AI","download_url":"https://codeload.github.com/19PINE-AI/principal-loyalty/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/19PINE-AI%2Fprincipal-loyalty/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35877013,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-25T02:00:06.922Z","response_time":64,"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-safety","ai-alignment","ai-safety","benchmark","knowledge-distillation","large-language-models","llm-agents","llm-evaluation","nlp","principal-agent","reinforcement-learning"],"created_at":"2026-07-25T11:01:35.663Z","updated_at":"2026-07-25T11:01:36.359Z","avatar_url":"https://github.com/19PINE-AI.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Principal Loyalty\n\n### Whose Side Is Your Agent On? Multi-Party Principal Loyalty in LLM Agents\n\n[![paper](https://img.shields.io/badge/paper-arXiv%3A2606.30383-b31b1b.svg)](https://arxiv.org/abs/2606.30383)\n[![license](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)\n\nMost LLM agents today operate in a digital world: they call APIs, browse, and\nserve the user who invoked them. A rapidly growing class of deployments is\n**multi-party** — the agent represents a **principal** (who briefs the agent,\nsends follow-up instructions, and receives results) while *also* conversing in a\nseparate channel with a **counterparty** whose interests may diverge:\nnegotiating with a vendor, screening inbound requests for an owner, mediating\nbetween employees. Here *\"help whoever you are talking to\"* is the wrong\nobjective; the agent must stay **loyal to the principal it represents** without\nover-refusing the principal's own cooperative requests.\n\nThis repository contains the benchmark, training recipes, evaluation harness,\nanalysis scripts, and companion website for our study of the **multi-party\nloyalty problem**.\n\n---\n\n## What's here\n\n| Contribution | Where |\n|---|---|\n| **PrincipalBench** — a 75-item multi-turn measurement instrument with leak probes, dual judges, and an integrity-audit gate | [`items/`](items/), [`src/`](src/) |\n| **(M1) Prompt-time loyalty scaffold** — seven prioritized rules open-coded from 50+ failure trajectories | [`src/loyalty.py`](src/loyalty.py), [`src/agent.py`](src/agent.py) |\n| **(M2) Per-token-KL distillation** — an on-policy recipe transferring a prompted Qwen3-32B teacher into 8B Qwen3 / Llama-3.1 students | [`scripts/pertoken_kl_collect.py`](scripts/pertoken_kl_collect.py), [`scripts/run_iter4_pertoken_kl.sh`](scripts/) |\n| **Reproducibility pipeline** — every paper number regenerates from raw trajectories | [`scripts/recompute_all.py`](scripts/recompute_all.py) |\n| **Companion website** — browse items, models, runs, and sample conversations | [`website/`](website/) |\n| **Paper** | [arXiv:2606.30383](https://arxiv.org/abs/2606.30383) · [`paper_arxiv.tex`](paper_arxiv.tex), [`paper_arxiv.pdf`](paper_arxiv.pdf) |\n\n---\n\n## Key findings\n\n- **A calibrated / over-refuse split.** Running PrincipalBench across 13 frontier\n  models exposes a sharp split — **≤20% harm** for calibrated models vs.\n  **53.6–75.3% harm** for over-refusers — that is invisible to single-turn\n  safety evaluations.\n- **The scaffold works.** Under the seven-rule loyalty scaffold, Claude-Sonnet\n  reaches 21/108 (19.4%) harm, and all nine calibrated frontier models hold\n  ≤20% harm.\n- **Distillation transfers.** Per-token-KL distillation is the strongest\n  open-weight recipe we measure, moving an 8B student to harm 33 / leak 13.\n- **A structural floor.** Both mechanisms move *along* a common\n  leak/over-refusal trade-off rather than crossing it — a floor that single-knob\n  RL (DAPO) also fails to break.\n\n---\n\n## Repository layout\n\n```\nprincipal-loyalty/\n├── src/                  # the benchmark harness — see docs/architecture.md\n│   ├── harness.py        #   trajectory runner: (subject, arm, item) → JSONL\n│   ├── items.py          #   item schema + loader\n│   ├── agent.py          #   agent under test: plain / prompted / scaffolded arms\n│   ├── counterparty.py   #   counterparty simulator (pressure strategies)\n│   ├── loyalty.py        #   externalized LoyaltyState (the M1 scaffold)\n│   ├── probe.py          #   leak-detection probe (lexical + LLM)\n│   ├── scorer.py         #   per-item / per-cell metric aggregation\n│   ├── reward.py         #   fast proxy reward for DAPO training\n│   └── vendors.py        #   unified vendor layer (Anthropic/OpenAI/Google/OpenRouter)\n├── items/                # benchmark items (JSON) — see docs/benchmark.md\n│   ├── v0/               #   50 training items\n│   ├── v0_75/            #   25 held-out items\n│   └── v0_5/             #   superseded dev-intermediate set (not part of release)\n├── data/                 # SFT / DPO / on-policy distillation datasets — see docs/training.md\n├── scripts/              # eval, training, analysis, figure, release scripts (see Key scripts below)\n├── figures/              # paper figures (PDF), regenerated by scripts/make_figs_arxiv.py\n├── website/              # static React companion site — see docs/website.md\n├── docs/                 # extended documentation — see the Documentation section below\n├── paper_arxiv.{tex,pdf,bib,bbl}, arxiv.sty, abstract.txt   # the paper\n├── RELEASE.md            # building the clean public release tree\n└── requirements.txt\n```\n\n\u003e **Note on large artifacts.** Raw run trajectories (`runs/`, 150+ GB) and Hydra\n\u003e training outputs (`outputs/`) are git-ignored. The repository ships the items,\n\u003e code, datasets, figures, and paper; trajectories are regenerated by re-running\n\u003e the harness (see [docs/reproduce.md](docs/reproduce.md)).\n\n### Key scripts\n\n`scripts/` holds the full research history; these are the entry points you'll\nactually use:\n\n| Script | What it does |\n|---|---|\n| [`run_traj_only.py`](scripts/run_traj_only.py) · [`multi_rollout_eval.py`](scripts/multi_rollout_eval.py) | Generate trajectories / run a multi-seed grid eval |\n| [`recompute_all.py`](scripts/recompute_all.py) | Recompute **every** paper number from `runs/` |\n| [`paired_seed_test.py`](scripts/paired_seed_test.py) · [`per_arm_xvendor_wilcoxon.py`](scripts/per_arm_xvendor_wilcoxon.py) | The paper's statistical tests |\n| [`make_figs_arxiv.py`](scripts/make_figs_arxiv.py) | Regenerate all paper figures |\n| [`pertoken_kl_collect.py`](scripts/pertoken_kl_collect.py) · [`run_iter4_pertoken_kl.sh`](scripts/run_iter4_pertoken_kl.sh) | Per-token-KL distillation (mechanism M2) |\n| [`run_dapo.sh`](scripts/run_dapo.sh) · [`run_full_pipeline.sh`](scripts/run_full_pipeline.sh) | DAPO baseline / end-to-end Llama pipeline |\n| [`build_website_data.py`](scripts/build_website_data.py) · [`build_release.py`](scripts/build_release.py) | Refresh the website data / build the clean release tree |\n\n---\n\n## Quick start\n\n```bash\n# 1. install (the harness itself needs only anthropic + openai)\npython3 -m venv .venv \u0026\u0026 source .venv/bin/activate\npip install -r requirements.txt\n\n# 2. set provider keys (only those you intend to use)\nexport ANTHROPIC_API_KEY=...\nexport OPENAI_API_KEY=...\nexport OPENROUTER_API_KEY=...\n\n# 3. generate trajectories for a subject across all arms on the v0 items\npython3 scripts/run_traj_only.py --seed-dirs runs/smoke_seed1 \\\n    --subject claude-sonnet --counterparty claude-sonnet \\\n    --items items/v0 --parallel 4\n\n# 4. multi-seed grid eval (trajectories + scoring + aggregation)\npython3 scripts/multi_rollout_eval.py --base runs/smoke \\\n    --seeds 5 --counterparty claude-sonnet --parallel 4\n```\n\nThe harness (`src/`) is a library, not a CLI — the scripts in `scripts/` drive\nit (see [docs/architecture.md](docs/architecture.md)). For the full evaluation\nsweep, training recipes, and figure regeneration, see the documentation below.\n\n---\n\n## Documentation\n\n| Doc | Contents |\n|---|---|\n| [docs/benchmark.md](docs/benchmark.md) | Item schema, the six cells, the three arms, leak probes, dual judges, the integrity-audit gate |\n| [docs/architecture.md](docs/architecture.md) | How the harness, scorer, and vendor layer fit together |\n| [docs/reproduce.md](docs/reproduce.md) | Reproducing every number and figure in the paper |\n| [docs/training.md](docs/training.md) | The per-token-KL distillation recipe and DAPO baselines |\n| [docs/website.md](docs/website.md) | Building and refreshing the companion site |\n| [RELEASE.md](RELEASE.md) | Building the clean public release tree |\n\n---\n\n## Citation\n\n```bibtex\n@misc{principalbench2026,\n  title         = {Whose Side Is Your Agent On? Multi-Party Principal Loyalty in LLM Agents},\n  author        = {Li, Bojie and Shi, Noah},\n  year          = {2026},\n  eprint        = {2606.30383},\n  archivePrefix = {arXiv},\n  primaryClass  = {cs.AI},\n  note          = {PrincipalBench},\n  url           = {https://arxiv.org/abs/2606.30383}\n}\n```\n\n## License\n\nReleased under the [MIT License](LICENSE).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F19pine-ai%2Fprincipal-loyalty","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F19pine-ai%2Fprincipal-loyalty","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F19pine-ai%2Fprincipal-loyalty/lists"}