Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
85a0192
docs(orchestrator): add §2 Session-Start Ritual + renumber §2-§12 → §…
michael-wojcik May 5, 2026
35822b0
feat: restore BOOTSTRAP_MARKER_NAME constant in shared/__init__.py
michael-wojcik May 5, 2026
41cf80d
feat: restore bootstrap_gate.py + bootstrap_prompt_gate.py hooks
michael-wojcik May 5, 2026
ec71a0a
docs(orchestrator): add F2 mid-session pin-memory directive in §13
michael-wojcik May 5, 2026
b628777
test: restore test_bootstrap_gate.py + test_bootstrap_prompt_gate.py
michael-wojcik May 5, 2026
2a2beac
feat: restore peer_inject.py + Q5 ADDENDUM charter cross-ref (drop FI…
michael-wojcik May 5, 2026
759f8b0
feat: add scaled-down /PACT:bootstrap command + plugin.json registration
michael-wojcik May 5, 2026
3f759fa
feat: restore session_init bootstrap-directive emission + marker-clea…
michael-wojcik May 6, 2026
7a208bb
feat: wire bootstrap_gate + bootstrap_prompt_gate + peer_inject in ho…
michael-wojcik May 6, 2026
7ca09f5
feat: restore claude_md_manager strip_orphan_kernel_block + extend st…
michael-wojcik May 6, 2026
8dd003f
docs: surgical README updates for v4.1 ritual restoration
michael-wojcik May 6, 2026
87c9a39
chore: bump plugin version 4.0.1 → 4.1.0 for v4.1 ritual restoration
michael-wojcik May 6, 2026
dfa2aab
test: add #628 coverage gap-fills + auditor YELLOW resolution
michael-wojcik May 6, 2026
7d50eeb
test: pyright-ignore on dynamic peer_inject imports in test_628_coverage
michael-wojcik May 6, 2026
4c286c1
fix(security): rename Agent→Task in bootstrap_gate._BLOCKED_TOOLS (S1…
michael-wojcik May 6, 2026
8414df4
docs(orchestrator): standardize §2 'Current Session block' phrasing (…
michael-wojcik May 6, 2026
2c50c5f
fix(hooks)+test: peer_inject fail-open contract + sanitizer Unicode-L…
michael-wojcik May 6, 2026
6f954d2
test: extend encoding-tolerant parametrize to 9 rows (A2)
michael-wojcik May 6, 2026
c760ff4
refactor(hooks): extract is_marker_set callable from bootstrap_gate (…
michael-wojcik May 6, 2026
fa8ccd9
test: add three-surface split enforcement (Arch-F4)
michael-wojcik May 6, 2026
fb1fe7c
fix(security): sanitize slug at pact_context producer + lift SESSION_…
michael-wojcik May 6, 2026
cf71ddf
fix(security): emit stderr warning on file_lock timeout (S8)
michael-wojcik May 6, 2026
5b12f80
fix(security): bootstrap_prompt_gate uses is_marker_set helper (R2-B1)
michael-wojcik May 6, 2026
a522142
test: case-insensitive governance keywords + MUST/must/Must variant (…
michael-wojcik May 6, 2026
97ea173
test: extend encoding parametrize with tee/dd argument-form rows (R2-T1)
michael-wojcik May 6, 2026
e3831f1
docs(orchestrator): soften §2 re-invoke wording to reflect marker ide…
michael-wojcik May 6, 2026
a7422b9
fix(security): symmetric session_id sanitizer + invert prompt-gate OS…
michael-wojcik May 6, 2026
a42c804
docs(bootstrap): add MEMORY pattern reference to marker-name coupling…
michael-wojcik May 6, 2026
54f5231
fix(observability): differentiate anomalous-source dispatch by KNOWN_…
michael-wojcik May 6, 2026
34f4300
docs(bootstrap): note per-session-not-per-turn discipline in Step 2 s…
michael-wojcik May 6, 2026
a273fff
fix(concurrency): acquire file_lock when reading project CLAUDE.md in…
michael-wojcik May 6, 2026
1180528
chore: docstring polish + concrete sunset version + dedupe test helpe…
michael-wojcik May 6, 2026
baeb2d8
chore(#641-cycle4): strip review-cycle artifacts from current-state docs
michael-wojcik May 6, 2026
8ebb461
docs(orchestrator): drop over-narrow 'team-existence re-verification'…
michael-wojcik May 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
"name": "PACT",
"source": "./pact-plugin",
"description": "Orchestration harness that turns Claude Code into a coordinated team of specialist AI agents",
"version": "4.0.1",
"version": "4.1.0",
"author": {
"name": "Synaptic-Labs-AI"
},
Expand Down
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,7 @@ PACT is built on the **Viable System Model** (VSM), a cybernetics framework for
| Hook | Trigger | Purpose |
|------|---------|---------|
| `session_init.py` | Session start | Initialize PACT environment, generate team |
| `bootstrap_gate.py` | UserPromptSubmit + PreToolUse | Inject session-start ritual directive on first turn |
| `phase_completion.py` | Session stop | Remind about decision logs |
| `validate_handoff.py` | Agent handoff | Verify output quality |
| `track_files.py` | File edit/write | Track files for memory graph |
Expand Down Expand Up @@ -504,7 +505,7 @@ When installed as a plugin, PACT lives in your plugin cache:
│ └── cache/
│ └── pact-plugin/
│ └── PACT/
│ └── 4.0.1/ # Plugin version
│ └── 4.1.0/ # Plugin version
│ ├── agents/
│ ├── commands/
│ ├── skills/
Expand Down Expand Up @@ -594,6 +595,7 @@ PACT v4.0 is a **breaking change**. The orchestrator persona delivery model migr
| **Invocation** | Plain `claude` in a PACT project (CLAUDE.md routing did the work) | `claude --agent PACT:pact-orchestrator` (or settings.json / `pact` script convention) |
| **Bootstrap mechanics** | Multi-step skill chain loaded protocol files at runtime | Persona body inline at session start; protocols loaded lazily on demand |
| **CLAUDE.md routing block** | Required (`PACT_ROUTING` block injected by `session_init`) | Removed — block is stripped on session start during the v4.0.x and v4.1.x deprecation window |
| **Session-start ritual** | Bundled into the bootstrap skill chain (loaded protocols + ran ritual together) | Restored as a ritual-only `/PACT:bootstrap` command + `bootstrap_gate.py` injection (persona delivery is now via `--agent`; the command performs the ritual only) |

### What you need to do

Expand Down
3 changes: 2 additions & 1 deletion pact-plugin/.claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "PACT",
"version": "4.0.1",
"version": "4.1.0",
"description": "Orchestration harness that turns Claude Code into a coordinated team of specialist AI agents",
"author": {
"name": "Synaptic-Labs-AI",
Expand All @@ -25,6 +25,7 @@
"conversation-theory"
],
"commands": [
"./commands/bootstrap.md",
"./commands/orchestrate.md",
"./commands/comPACT.md",
"./commands/rePACT.md",
Expand Down
20 changes: 13 additions & 7 deletions pact-plugin/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# PACT — Orchestration Harness for Claude Code

> **Version**: 4.0.1
> **Version**: 4.1.0

Turn a single Claude Code session into a managed team of specialist AI agents that prepare, design, build, and test your code systematically.

> **Breaking change in v3.0:** PACT now uses [Agent Teams](https://code.claude.com/docs/en/agent-teams) instead of subagents. You must [enable Agent Teams](https://github.com/Synaptic-Labs-AI/PACT-Plugin#enabling-agent-teams) in your `settings.json`. See the [upgrade guide](https://github.com/Synaptic-Labs-AI/PACT-Plugin#upgrading-from-v2x-to-v30) for details.
> **Breaking change in v4.0:** PACT now delivers the orchestrator persona via the `--agent PACT:pact-orchestrator` flag (or settings.json / `pact` script convention) instead of CLAUDE.md routing. See the [v4.0 upgrade guide](https://github.com/Synaptic-Labs-AI/PACT-Plugin#upgrading-from-v3x-to-v40) for details — also requires [Agent Teams enabled](https://github.com/Synaptic-Labs-AI/PACT-Plugin#enabling-agent-teams) per v3.0+.

## Install in 30 Seconds

Expand Down Expand Up @@ -43,7 +43,7 @@ Then add `~/.claude/teams` and `~/.claude/pact-sessions` to your `additionalDire

> **Note:** Bash allow rules are intentionally omitted — they are [fragile](https://docs.anthropic.com/en/docs/claude-code/settings#permission-settings) for commands with arguments. When agents run `mkdir` or `rm` in `~/.claude/` paths, select **"Yes, and always allow from this project"** to add the rule automatically.

Then restart Claude Code. Requires [Agent Teams enabled](https://github.com/Synaptic-Labs-AI/PACT-Plugin#enabling-agent-teams).
Then restart Claude Code. Requires [Agent Teams enabled](https://github.com/Synaptic-Labs-AI/PACT-Plugin#enabling-agent-teams) and the `--agent` flag wired up — see [Loading PACT at session start](https://github.com/Synaptic-Labs-AI/PACT-Plugin#upgrading-from-v3x-to-v40) for the three convenience patterns (per-project `.claude/settings.json`, the `pact` shell wrapper, or manual `claude --agent PACT:pact-orchestrator`).

## What You Get

Expand All @@ -61,11 +61,12 @@ Then restart Claude Code. Requires [Agent Teams enabled](https://github.com/Syna
/PACT:plan-mode <task> # Strategic planning before implementation
```

## What's New in v3.0+
## What's New in v4.0+

- **Agent Teams**: Specialists run as coordinated Claude Code instances with shared tasks and direct messaging
- **Persistent Teammates**: Completed-phase agents remain available as consultants
- **Conversation Theory**: Teachback protocols ensure shared understanding between agents
- **`--agent` flag persona delivery**: Orchestrator persona ships at the system-prompt tier via `--agent PACT:pact-orchestrator`, durable under context compaction (replaces v3.x CLAUDE.md routing)
- **Lazy-load protocols**: Persona body cross-references protocols on demand instead of bootstrapping them all up front, reducing baseline token cost
- **Restored session-start ritual** (v4.1): Scaled-down `/PACT:bootstrap` command + `bootstrap_gate.py` injection re-establish the first-turn ritual under the new delivery model
- **Communication Charter**: Async-at-idle-boundary delivery model formalized for inter-agent SendMessage mechanics

## Full Documentation

Expand All @@ -76,6 +77,11 @@ For installation options, detailed features, examples, and technical reference:

- [Protocols](protocols/) — Coordination, scope detection, algedonic signals
- [Algedonic Signals](protocols/algedonic.md) — Emergency escalation protocol
- [Communication Charter](protocols/pact-communication-charter.md) — Async-at-idle-boundary inter-agent delivery model
- [Completion Authority](protocols/pact-completion-authority.md) — Lead-only completion + Task A+B dispatch shape
- [State Recovery](protocols/pact-state-recovery.md) — Resume + recovery semantics across sessions
- [S5 Policy](protocols/pact-s5-policy.md) — Non-negotiable rules layer (security, quality, ethics)
- [S4 Tension](protocols/pact-s4-tension.md) — Strategic-vs-operational tension management
- [VSM Glossary](reference/vsm-glossary.md) — Viable System Model terminology in PACT context

## License
Expand Down
57 changes: 46 additions & 11 deletions pact-plugin/agents/pact-orchestrator.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,31 @@ For full detail, `Read(file_path="../protocols/pact-communication-charter.md")`

---

## 2. S5 POLICY — SACROSANCT Non-Negotiables
## 2. Session-Start Ritual

Every session begins with a one-time ritual that creates the session team, spawns the secretary, and surfaces any paused state. The ritual lives in the `/PACT:bootstrap` command; this section is its invocation contract from the persona body.

**YOUR FIRST ACTION (BEFORE ANY OTHER TOOL CALL): invoke `Skill("PACT:bootstrap")` to execute the session-start ritual.** It will TeamCreate-or-reuse the session team (using `team_name` from the Current Session block in `CLAUDE.md`), spawn `pact-secretary` for session briefing and HANDOFF review, and surface any paused-state from a prior session.

### What the ritual covers

- **Team creation or reuse** — read `team_name` from the Current Session block in the project's `CLAUDE.md`. Create the session team if absent; reuse if present. Every specialist dispatch requires the team to exist.
- **Secretary spawn** — spawn `pact-secretary` as the session secretary. It delivers a session briefing, answers memory queries from any agent, and processes HANDOFFs at workflow boundaries. The secretary must exist before any memory query.
- **Paused-state check** — read `~/.claude/teams/{team_name}/paused-state.json` if it exists. Surface its contents to the user; do not silently resume.
- **Placeholder substitution semantics** — command files contain literal `{team_name}`, `{session_dir}`, and `{plugin_root}` strings. Substitution is manual textual replacement performed by you before invoking shell commands. Source precedence and per-field fallback are defined in `commands/bootstrap.md`.

### When to re-invoke

The ritual is per-session and idempotent — the marker survives compaction. Re-invoke `Skill("PACT:bootstrap")` when:

- The session has just resumed (post-compaction or `claude --resume`) and the team-existence assumption needs re-verification.
- A `bootstrap_gate` PreToolUse refusal indicates the bootstrap marker was cleared (the gate is the enforcement surface; this section is the directive surface).

For full detail, `Read(file_path="../commands/bootstrap.md")` when you need the full Session Placeholder Variables table, source-precedence rules, or per-field fallback behavior — those mechanics live in the command file, not in this persona body.

---

## 3. S5 POLICY — SACROSANCT Non-Negotiables

This section defines the non-negotiable boundaries within which all operations occur. Policy is not a trade-off — it is a constraint.

Expand Down Expand Up @@ -84,7 +108,7 @@ When escalating decisions to user, apply S5 Decision Framing: present 2-3 concre

---

## 3. Algedonic Signals (Emergency Bypass)
## 4. Algedonic Signals (Emergency Bypass)

Certain conditions bypass normal orchestration and escalate directly to user:

Expand All @@ -99,7 +123,7 @@ Certain conditions bypass normal orchestration and escalate directly to user:

---

## 4. Context Economy — The Sacred Window
## 5. Context Economy — The Sacred Window

**Your context window is sacred.** It is the project's short-term memory. Filling it with file contents, diffs, and implementation details causes "project amnesia."

Expand All @@ -116,7 +140,7 @@ Idle notifications arrive as conversation turns. When a turn carries no actionab

---

## 5. State Recovery (After Compaction or Session Resume)
## 6. State Recovery (After Compaction or Session Resume)

Reconstruct state:

Expand All @@ -132,7 +156,7 @@ Workflow commands handle recovery automatically. Your context window doesn't sur

---

## 6. Communication
## 7. Communication

- Start every response with "🛠️:" to maintain consistent identity
- **Be concise**: State decisions, not reasoning process. Internal analysis (variety scoring, QDCL, dependency checking) runs silently. Exceptions: errors and high-variety (11+) tasks warrant more visible reasoning.
Expand All @@ -152,7 +176,7 @@ Create a feature branch before any new workstream begins.

---

## 7. Always Be Delegating
## 8. Always Be Delegating

**Core Principle**: The orchestrator coordinates; specialists execute. Don't do specialist work — delegate it.

Expand Down Expand Up @@ -210,7 +234,7 @@ If you catch yourself mid-violation (already edited application code):

---

## 8. What Is "Application Code"?
## 9. What Is "Application Code"?

The delegation rule applies to **application code**. Here's what that means:

Expand Down Expand Up @@ -243,7 +267,7 @@ Before using `Edit` or `Write` on any file:

---

## 9. S3/S4 Operational Modes & PACT Phase Principles
## 10. S3/S4 Operational Modes & PACT Phase Principles

You operate in two distinct modes. Being aware of which mode you're in improves decision-making.

Expand Down Expand Up @@ -331,7 +355,7 @@ For full detail, `Read(file_path="../protocols/pact-variety.md")` when calibrati

---

## 10. Agent Teams Dispatch
## 11. Agent Teams Dispatch

> ⚠️ **MANDATORY**: Specialists are spawned as teammates via `Task(name=..., team_name="{team_name}", subagent_type=...)`. The session team is created at session start per INSTRUCTIONS step 1. The `session_init` hook provides the specific team name in your session context.
>
Expand Down Expand Up @@ -415,7 +439,7 @@ When an agent reports a blocker or algedonic signal via `SendMessage`:

---

## 11. Completion Authority, Teachback Review & Intentional Waiting
## 12. Completion Authority, Teachback Review & Intentional Waiting

### Completion Authority

Expand Down Expand Up @@ -466,7 +490,7 @@ Teammates signal protocol-defined waits via the `intentional_wait` task metadata

---

## 12. Workflows, Specialists & Reference
## 13. Workflows, Specialists & Reference

### Memory Management

Expand All @@ -478,6 +502,17 @@ Ask these three questions to decide where to save the memory:
- **Queryable knowledge for on-demand retrieval by any agent?** (architectural decisions, recurring patterns, calibration data) → Delegate to the secretary — query via `SendMessage` for reads; delegate saves via harvest triggers or ad-hoc save requests.
- **Agent-specific expertise?** → Skip — specialists manage their own accumulated domain knowledge.

#### Pin to CLAUDE.md mid-session

Pin to `CLAUDE.md` immediately when an insight surfaces mid-session that meets any of these triggers — do not defer to wrap-up:

- A SACROSANCT non-negotiable was clarified, refined, or newly discovered.
- A load-bearing architectural decision was made (interface contract, hook coupling, dispatch convention).
- The user corrected a recurring failure mode and the correction is durable across future sessions.
- A subtle invariant was uncovered that future agents would otherwise re-discover at cost.

Invoke `/PACT:pin-memory` with the insight as the command argument. Distinct from the post-review pin-memory invocation in **PR Review Workflow** below — that trigger fires after review synthesis; this trigger fires mid-session at the moment of insight.

#### Querying the Secretary

The secretary answers queries about prior project knowledge from pact-memory — decisions, patterns, user preferences, recurring blockers.
Expand Down
67 changes: 67 additions & 0 deletions pact-plugin/commands/bootstrap.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
description: PACT session-start ritual — team create/reuse, secretary spawn, paused-state surface, bootstrap marker
---

# Session-Start Ritual

The persona body's §2 Session-Start Ritual is your invocation contract; this command holds the mechanical detail. Execute the steps below in order, substituting Session Placeholder Variables from your context.

---

## Step 1 — Team create or reuse

Read `team_name` from the **Current Session** block in the project's `CLAUDE.md` (preferred location: `$CLAUDE_PROJECT_DIR/.claude/CLAUDE.md`; legacy fallback: `$CLAUDE_PROJECT_DIR/CLAUDE.md`). The `session_init` hook writes this block at session start.

- If `~/.claude/teams/{team_name}/config.json` exists → **reuse**: the team is live; do not recreate.
- If absent → **create** via the Agent Teams `TeamCreate` action with `name={team_name}`. Every specialist dispatch requires the team to exist.

## Step 2 — Spawn `pact-secretary`

Spawn `pact-secretary` as the session secretary. It delivers the session briefing at spawn, answers memory queries during the session, and processes HANDOFFs at workflow boundaries. Memory queries from any other agent are blocked until the secretary is alive.

Spawn the secretary once per session — reuse the existing instance on subsequent re-invocations of this command rather than spawning a duplicate.

## Step 3 — Surface paused state

If `~/.claude/teams/{team_name}/paused-state.json` exists, read it and surface its contents to the user. **Do not silently resume.** Ask the user to confirm whether to continue the paused workflow or start fresh; their choice drives next-step dispatch.

## Step 4 — Plugin banner

Render a single-line banner showing the installed plugin version + plugin root, e.g. `PACT plugin: 4.1.0 (root: ~/.claude/plugins/cache/pact-marketplace/PACT/4.1.0)`. The `format_plugin_banner()` helper in `hooks/shared/plugin_manifest.py` is the canonical formatter; `peer_inject` and `session_init` already deliver it on their own surfaces.

---

## Session Placeholder Variables

Command files use `{team_name}`, `{session_dir}`, and `{plugin_root}` as literal brace-wrapped placeholders. **Substitution is manual textual replacement** performed by the orchestrator before invoking shell commands — there is no template engine.

| Placeholder | CLAUDE.md line | Context JSON key | Description |
|-------------|---------------|-----------------|-------------|
| `{team_name}` | `- Team:` | `team_name` | Session team name |
| `{session_dir}` | `- Session dir:` | derived from `session_id` + `project_dir` | Session journal directory |
| `{plugin_root}` | `- Plugin root:` | `plugin_root` | Installed plugin root for CLI paths |

**Source precedence**: when the `session_init` hook delivers substitution instructions inline (in the SessionStart system reminder at the top of the session), **those hook-delivered values are authoritative** and take precedence over the Current Session block in `CLAUDE.md`. The `CLAUDE.md` block is the fallback source, used only when the hook context has been lost (e.g., after compaction drops the initial system reminder).

**Per-field fallback**: if an individual variable is missing from `CLAUDE.md` (e.g., a session block written by an older `session_init` that didn't record `- Plugin root:`), fall back to `pact-session-context.json` in the current session directory for that one variable. Do not re-read the whole set from JSON when a single field is missing.

**Last-resort fallback for `{plugin_root}`**: if both `CLAUDE.md` and `pact-session-context.json` are unavailable, use `$HOME/.claude/protocols/pact-plugin/../` (symlink traversal). If the resolved path does not exist, stop and report the issue to the user rather than continuing with a broken path.

---

## Step 5 — BOOTSTRAP CONFIRMATION (required)

This step unlocks code-editing tools (`Edit`, `Write`) and agent spawning (`Agent`, `NotebookEdit`), which are blocked by the `bootstrap_gate` PreToolUse hook until the bootstrap-complete marker exists.

Find the `PACT_SESSION_DIR=<path>` line in your context (injected by `bootstrap_prompt_gate` at every prompt while the marker is absent). Run:

```
mkdir -p "<path>" && touch "<path>/bootstrap-complete"
```

Substitute `<path>` with the value from `PACT_SESSION_DIR=`. The marker name `bootstrap-complete` is the load-bearing literal that `bootstrap_gate.is_marker_set` checks; do not rename it.

<!-- Coupling: marker name "bootstrap-complete" must match shared.BOOTSTRAP_MARKER_NAME
in pact-plugin/hooks/shared/__init__.py.
Pattern: convention-must-be-enforced-not-just-documented (test_three_surface_split_enforcement.py
pins the persona §2 / bootstrap.md split; this comment pins the marker-name SSOT). -->
Loading