Concepts

The mental model behind ginee. Worth reading once; you’ll use the same patterns on every project.

The 7-cardinal team

ginee ships exactly 7 cardinal roles — every adopter project has the same shape:

Role Concerns
team-lead Orchestrator. Dispatch routing, lifecycle gates, discovery / rediscovery, post-acceptance hook, staleness checks. Authors (D25) CRs · project-instruction file · work-breakdown doc.
solution-architect Classical architect (D25, refined #182) — three activities, all OUTSIDE implementation phases. Design (Phase 1 elicit FRs/NFRs/Constraints + derive ASRs via ATAM utility tree; Phase 2 target architecture; Phase-1 output post-implementation-governance: yes/no). Review (out-of-process — periodic / drift / explicit user; against architecture-of-record, never engineer mid-flight proposals). Governance (Phase 7 only, sporadic — fires on (a) task introduced architectural changes OR (b) Phase-1 flag; default = skip). Phase 4/5/6 SA dispatch categorically refused. Authors architecture doc · ADRs · diagrams · requirements register · ASR utility tree — implementation rendering (function/member names · line numbers · commit SHAs · handler-body snippets · “how to wire it” prescriptions) forbidden in every artefact.
ai-engineer AI-asset + doc context economy, file-splitting, load topology, lossless restructures. D25 counterpart generalized — was SA-only, now all-roles. Between-phase only.
frontend-engineer Client / UI implementation, mockup ownership, state, styling, fetch / realtime client wiring. Authors (D25) frontend READMEs · component docs · style guides.
backend-engineer Server / API implementation, ORM entities, schema, realtime hub, auth middleware, wire contract. Authors (D25) backend READMEs · API docs · service docs.
devops-engineer IaC, Dockerfiles, orchestration, CI workflows, gateway config, secrets, cost tracking. Authors (D25) CI/CD guide · infra runbooks · deployment guides.
qa-engineer Scenario specs, e2e / functional / smoke tests, harness assertions, fixtures, seed scripts. Authors (D25) test plans · scenario docs · QA reports.

Why exactly 7? Two slots are universal — every project has an orchestrator and AI-asset / doc upkeep. The remaining 5 cover the engineering surfaces every software project has: client, server, infra, quality, plus the architect who governs the design across them.

Specialists in extras/roles/ — security · ml · mobile · sre · data — are opt-in. Adopt them when discovery surfaces the matching domain.

Custom roles live under local/roles/ and register under team-lead. Use the core/templates/role-authoring-template.md shape.

Artefacts are written for humans + LLMs

ginee artefacts on GitHub — filed bugs · feature requests · sub-issue dispatches · framework-authored comments · PR descriptions — are read by both audiences. A human contractor opens issue #142 and needs to grok the request cold. A cardinal LLM picks up the same issue six hours later and routes off the framework prefix. The default LLM-only voice ([6:frontend-engineer] Stage 1 forensic — confirm Bug C/D root cause on demo-gha data (#92 iteration 1)) fails the human; a pure marketing title (Fix the deploy bug) loses the framework hooks. Both audiences MUST be served.

The binding ships as a 5-item audience check on ginee-file-* skill self-lint (title in user-facing language · 2-4 sentence human Summary · numbered repro steps on bugs · framework-internal sections after the human summary · forbidden-identifier list scrubbed from title). Full spec: core/protocols/doc-authoring-protocol.md § Audience check. Adopters writing custom issue templates under local/ follow the same convention.

Compliance enforcement (Claude adapter)

Class A action-time gates layer onto charter rules so they’re enforced at the tool-call layer, not via always-loaded text alone. Two pieces ship in the parent playbook (#135):

Opt out per-tactic via local/framework.config.yaml § compliance.disabled: [<tactic-id>]. Bypass per invocation via SKIP_GINEE_COMPLIANCE=1 (emergency only).

Phased task lifecycle

Every non-trivial task runs through Phases 1–8. Specialists within a phase run in parallel where independent; phases overlap wherever a contract surface decouples them.

Phase Goal Acceptance
1. Analysis Bound scope; identify touched domains. (D25) SA elicits FRs/NFRs/Constraints + derives ASRs via ATAM; resolves greenfield-vs-delta mode. Scope clear enough to plan Phase 2; ≤ 1 unresolved scope question; ASR utility tree covers every quality-attribute-driver touched
2. Design Lock contracts (architecture, mockup, wire, work breakdown). (D25) SA authors target architecture per resolved mode. Fixed contract surfaces; harness green; cross-refs resolved; ASRs traceable to ADRs
3. Design review Synchronous user-approval gate on Phase 2 Explicit user approval
4. Implementation Code mirroring approved contracts. (#182) SA categorically refused — engineer-surfaced architectural-delta routes through team-lead gate → user picks defer or re-enter Phase 1–2. Compiles; no new lint errors; engineer self-verify per core/protocols/engineer-self-verify.md — every change-scoped suite available to the role runs green OR carries an n/a / stale cite
5. Testing QA backstop — independent re-execution of every change-scoped suite the engineer reported + AC-compliance verification + manual smoke. NOT first-pass discovery; Phase 4 self-verify already gated those suites. (#182) SA categorically refused — red NFR-oracle routes to Phase 6 or team-lead gate. Touched-surface oracles green on QA re-run; AC compliance verified; manual-smoke report recorded
6. Bug fixing Resolve defects from Phase 5. (#182) SA categorically refused — architectural-delta fixes route through team-lead gate. Change-scoped oracles green; no regressions in touched surfaces
7. SA governance review (conditional, #182) solution-architect checks invariants — fires only on (a) task introduced architectural changes OR (b) Phase-1 post-implementation-governance: yes. Default = skip. APPROVE or RETURN-TO-engineer with findings; ASR coverage verified
8. User approval User confirms delivered work TODO ☐ → ☒; issue closed; delivery finalize per mode

Auto mode (D12) — prefix a task with auto: to elide intermediate gates (Phase 3 design review, iteration check-ins, engineer “stop and confirm”). Phase 8 becomes a single delivery handoff with Accept / Feedback / Reject. Forced back to interactive on UX changes, repeated defects, cross-domain cycles, or destructive actions.

Lite mode — prefix a task with lite: (alias direct:) to skip Phase 1–3 entirely for trivial scope (typo · single-label tweak · single-doc-bullet change). Phase 4 dispatches one named cardinal directly; Phases 5–8 run normally. CR / ADR / Phase 7 / Phase 8 gates remain. Composes with every other prefix — e.g. auto: lite: fix typo in CONCEPTS.md. Full spec — migrations/lite-mode.md.

Heavy-role bypass. team-lead + solution-architect are invocation-gated across Phase 4–7, not phase-gated — default is skip; presence requires an affirmative trigger (sub-issue routing artefact · SA-owned-file edit · NFR-oracle red · ## Open issues / ## Hand-off / Status: In-progress on cardinal return · cross-domain bug · multi-cardinal PR). Phases 1 / 2 / 3 / 8 (team-lead) + Phases 1 / 2 / 7 (SA) remain load-bearing. Full spec — core/protocols/heavy-role-bypass.md · migration — migrations/heavy-role-bypass.md.

QA pixel-check (optional Phase 5). Mockup graduates from design reference to runtime oracle — Phase 5 renders the app + reads the mockup at a shared seed-state and pixel-diffs. Off by default; opt in via qa.pixel-check.enabled: true in local/framework.config.yaml. Drift routes per source — app regression → front-end engineer; mockup outdated → mockup owner; seed wrong → seed-script owner; tolerance too tight → team-lead. Adopter picks alignment direction (mockup-follows-seed or seed-follows-mockup). Full spec — core/protocols/pixel-check-protocol.md · migration — migrations/qa-pixel-check.md.

Engineer self-verify before QA hand-off (strict Phase 4 gate). Phase 4 acceptance raised — engineers (frontend / backend / devops) MUST run every change-scoped suite available to the role in a fix → re-test loop until green before any QA / team-lead hand-off. Red suite is triaged as real defect (engineer fixes in-task) or stale oracle (engineer’s intentional contract change made the assertion obsolete — flag <suite> stale — <reason>; QA oracle update needed; engineer MUST NOT edit the test). Skip rules cite <suite> n/a — <reason> (runner not configured · not exercised by change · out of engineer reach). QA’s Phase 5 pass is backstop — MUST independently re-execute + verify AC compliance — never trusts a green engineer log alone. Change-scoped only; full regression remains opt-in. Non-compliance blocks Phase 4 acceptance.

Claude-adapter enforcement (per playbook #135):

Force class Surface What it does
H — always-loaded text core/process/phase-4-implementation.md § Acceptance · core/process/phase-5-testing.md § Goal · engineer + qa role kernels Strict MUST language bound at every dispatch load.
D — UserPromptSubmit keyword trigger (T5) adapters/claude/hooks/keyword-triggers.yaml § engineer-self-verify When user prompt mentions an engineer cardinal · Phase 4 · self-verify · hand-off → prepends the protocol excerpt (matrix · triage · row contract · QA backstop) as [ginee:context:engineer-self-verify].
D — PreToolUse SendMessage carry-forward (T8) adapters/claude/hooks/carry-forward-rules.yaml per engineer cardinal Warm-engineer continuations MUST cite the rule in [carry-forward] Remember: …; hook blocks (exit 2) otherwise.
A indirect — deterministic template (T10) adapters/claude/commands/ginee-phase-report.md /ginee-phase-report skeleton lands per-role Verification-log row skeleton (PASS / n/a / stale forms) at composition time; replaces drift-prone free-form.

Full spec — core/protocols/engineer-self-verify.md.

QA defect-reproducer test — Phase 5 → Phase 6 contract. Every defect QA observes in Phase 5 routes to Phase 6 with a committed failing test that reproduces it — fails today against the broken behaviour, passes once fixed. The engineer’s fix-oracle is deterministic (“test passes locally”), not informal (“works on my machine”). The test also becomes a permanent regression gate. Layer choice per defect class (functional · e2e · unit · script · smoke · pixel-check) — core/roles/qa-engineer.details.md § Test-layer selection per defect class. Untestable defects (pure visual judgement no pixel-diff captures · interactions requiring a real human · timing-sensitive observations no fixture reproduces) flag testable: false + rationale; Phase 6 falls back to description-only dispatch. Team-lead surfaces a process-concern advisory when testable: false ratio exceeds qa.defect-reproducer.testable-false-threshold in local/framework.config.yaml (default 20%) — informational, not a blocker. QA’s Phase 6 re-verification sweep is not replaced; the reproducer tightens the engineer-fix loop. Full spec — core/roles/qa-engineer.md § Defect-reproducer authoring discipline · migration — migrations/defect-reproducer-contract.md.

Compliance — Bash hook (T3)

A second PreToolUse hook (#139) matches the Bash tool and blocks four destructive shell-command patterns: git commit --no-verify, git push --force on main / master, git reset --hard (with SKIP_GINEE_COMPLIANCE bypass), and gh pr create without --body / --draft. Allowlist preserves common legitimate workflows (force-with-lease on feature branches, soft reset, draft PRs).

Opt out per-tactic: local/framework.config.yaml § compliance.disabled: [pretooluse-bash-hook]. Full spec: migrations/pretooluse-bash-hook.md.

Dispatch rules

Rule Action
Independent specialists in one phase One message with N dispatch calls — never serialize across messages
Cross-phase overlap (e.g. test authoring during implementation) One message; each prompt names the shared contract surface
Doc-only changes solution-architect alone (or mockup-owning role alone for mockup-only)
Infra change affecting application config Service-owner first (confirms app reads the new value), then devops-engineer
Pre-dispatch scope-size classifier (#168) Before every cardinal dispatch, team-lead emits one of ≤15m · 15-60m · >60m + one-line signal. 15-60m / >60m load core/protocols/iteration-protocol.md + require cardinal ## Estimate (sub-task decomposition + per-task minutes) returned before any edit. ≤15m skips both — class is recorded explicitly on the dispatch payload + sub-issue, not silently elided. lite: prefix auto-classifies as ≤15m. Full spec — migrations/estimation-gate-fires.md.

Strict-domain rule. A bug in domain X is fixed by the engineer who owns X — never by an adjacent specialist “while they’re in the area.” Cross-domain bugs require collaboration, not single-specialist heroics.

Compliance statusline (T4)

Tactic 4 of the parent playbook ships a single-line statusline (#140) that surfaces compliance state in Claude Code’s persistent status row — issue number · trailer status · cap-bytes headroom on the tightest hot-spec file. Class G (visible state, no enforcement) — partner to the action-time gates from T2 / T3.

Wire via .claude/settings.json § statusLine; opt out per-tactic: local/framework.config.yaml § compliance.disabled: [compliance-statusline]. Full spec: migrations/compliance-statusline.md.

Compliance — Tier 2 hooks (T5 / T6 / T7 / T8)

Four cross-platform hooks complete the playbook’s prompt-time / action-time / turn-time enforcement layers. All exit 0 on uncaught errors (fail-open); each carries a single compliance.disabled: [<tactic-id>] opt-out.

Tactic Event Force class What it does
T5 — UserPromptSubmit (#141) UserPromptSubmit D (prompt-time anchor) Scans the user prompt for ginee task keywords (pick up #N · auto: · branch: / wt: / commit: · /ginee-update · triage · address review · @<role> / dispatch); prepends a [ginee:context:<label>] spec excerpt via hookSpecificOutput.additionalContext. Patterns + bodies in adapters/claude/hooks/keyword-triggers.yaml.
T6 — PostToolUse self-check (#142) PostToolUse on Edit\|Write\|MultiEdit B (action-time injection) After every successful edit on core/**, injects a ≤ 6-line reminder (frontmatter · cap-bytes · D-free · lossless · always-loaded surface) for the next LLM action. Coexists with the structural context-economy gate in the same matcher entry. Skips tests/** · local/** · adapters/** · extras/**.
T7 — Stop (#143) Stop C (turn-time gate) Refuses turn-end (exit 2) on incomplete-work signals — cardinal return missing <!-- self-lint: pass --> · gh pr create issued without acceptance under ci-watch-policy: poll · open ginee:in-progress issue on the current <N>- branch with no Phase-8 close. Anti-loop guard on stop_hook_active (never traps).
T8 — PreToolUse SendMessage (#144) PreToolUse on SendMessage D (prompt-time anchor, per-continuation) Blocks (exit 2) warm-cardinal continuations whose first non-blank line does not lead with [carry-forward] Remember: <rule>. Rule per target cardinal in adapters/claude/hooks/carry-forward-rules.yaml. Out of scope: Agent (first dispatch). Defeats warm-cardinal drift over multi-dispatch spans.

Wire via .claude/settings.json; auto-merged by /ginee-update. Bypass per call: SKIP_GINEE_COMPLIANCE=1. Opt-out tactic-ids: user-prompt-submit-hook · posttooluse-edit-hook · stop-hook · pretooluse-send-message-hook. Full specs: migrations/user-prompt-submit-hook.md · migrations/posttooluse-edit-hook.md · migrations/stop-hook.md · migrations/carry-forward-injection.md.

Compliance — Tier 3 closeout (T9 / T10 / T11 / T12 / T13)

The last batch of the maximum-force Claude playbook ships the recency-optimisation pass + slash command suite + main-thread permission lockdown + session-resume hook. Adopter-facing surface stays unchanged for the prior tiers; T9–T12 add the always-loaded recency floor, deterministic templates for drift-prone compositions, the off-context-with-warm-continuity execution default, and the session-boundary anchor.

Tactic Surface Force class What it does
T9 — CLAUDE.md bookending (#145) CLAUDE.md + adapters/claude/CLAUDE-pointer.md H (always-loaded text, recency-optimised) 5 hard constraints (self-lint marker · SA never edits · context-economy trailer · D-free runtime · local/** only via discovery) appear verbatim at the top AND the bottom. LLMs read first / last carefully; middle drifts.
T10 — slash command suite (#146) .claude/commands/ginee-*.md A indirect (deterministic templates) Six commands replace LLM free-form composition: /ginee-dispatch · /ginee-phase-report · /ginee-self-lint · /ginee-commit · /ginee-pr · /ginee-issue-pickup. Each lands the schema skeleton + filling instructions in the prompt at composition time.
T11 — main-thread permission lockdown + dispatch-cap (#147) .claude/settings.json § permissions.deny + local/framework.config.yaml § warm-reuse.dispatch-cap A + F integrated Blocks framework-side Edit / Write / MultiEdit + destructive Bash from the main thread; real work routes through cardinals. Per-issue warm registry honours D43 plumbing + soft cap (default 15) — over-cap → forced-fresh + ## Carry-forward summary payload preserves prior decisions.
T12 — SessionStart resume (#148) SessionStart hook D (session-boundary anchor) At conversation start, scans issue/<N>-… branch state + open ginee:in-progress GitHub issues; injects [ginee:resume] block via hookSpecificOutput.additionalContext. Quiet on empty; offline-safe.
T13 — Optimized-By attestation (sister tactic, push-time) PreToolUse Bash hook (ask-mode) A consent-required — new force-class axis When git push would push a range carrying Optimized-By: ai-engineer trailer in any commit, scans the session transcript for an Agent(subagent_type=ai-engineer) dispatch. Absent → emits permissionDecision: "ask" so Claude Code surfaces its native permission prompt; user picks allow (cross-session optimization · manual lossless pass · WIP push) or deny (cancel + dispatch first). Path-agnostic — works equally on framework-self-dev (core/** · adapters/** · extras/**) and adopter pushes (docs · prompts · local/). Closes the trailer-claim loophole the gate could not catch on its own.

Wire via .claude/settings.json; auto-merged by /ginee-update. Adopter .claude/commands/ populated by install.{ps1,sh}. New opt-out tactic-ids: slash-commands · main-thread-permissions · session-start-hook · optimized-by-attestation. Full specs: migrations/claude-md-bookending.md · migrations/slash-commands-suite.md · migrations/warm-cardinal-default.md · migrations/session-start-hook.md · migrations/optimized-by-attestation.md.

Iteration protocol

For Phase 4 / 5 / 6 / 7 work above 15 min OR any timeframe-bounded task:

  1. Estimation-first dispatch. Each specialist returns task decomposition + per-task minutes before editing.
  2. Synthesis. Orchestrator (or PM) synthesizes all specialist proposals into one batch for user approval.
  3. 3–5 min iterations. Each ends in a stoppable intermediate state — visible result, no half-finished edit on disk.
  4. Stop anywhere. User can interrupt at any iteration boundary; resume next session with zero rework.

Source-of-truth ownership

Per-project, the table in local/bindings.md § Source-of-truth ownership maps:

Roles never read raw docs/** “before any work.” The index is the only default read surface; full source loads only when verbatim wording matters.

D25 doc-ownership map — per core/protocols/doc-roles.md § Authorship:

Doc class Owner
Architecture doc · ADRs · diagrams · requirements register (local/requirements.md) · ASR utility tree (local/asr-utility-tree.md) solution-architect
CRs · project-instruction file · work-breakdown team-lead
CI/CD guide · infra runbooks · deployment guides devops-engineer
Backend READMEs · API docs · service docs backend-engineer
Frontend READMEs · component docs · style guides frontend-engineer
Test plans · scenario docs · QA reports qa-engineer
Mockup mockup-owning role (default frontend-engineer)

Every non-SA-owned doc edit touching architectural concerns is SA-reviewed for architectural coherence — but only at Phase 7 (conditional) or out-of-process Review, never as a Phase 4/5/6 dip (#182). ai-engineer runs shape + load-topology passes across the whole doc set (was SA ↔ ai-engineer pre-D25; now all-roles ↔ ai-engineer).

Classical-architect SA model (D25, refined #182)

Three activities, all OUTSIDE implementation phases (Phase 4 / 5 / 6):

Activity When Output
Design Phase 1 elicit + Phase 2 target architecture local/requirements.md (FRs/NFRs/Constraints) · local/asr-utility-tree.md (ASRs derived via ATAM) · architecture doc · ADRs · diagrams. Phase-1 also records post-implementation-governance: yes/no — team-lead consumes to gate Phase 7.
Review Out-of-process — periodic / accumulated drift / explicit user request. NEVER tied to a task’s Phase 4/5/6. Verdict on the architecture-of-record (does it still serve current FRs/NFRs?). APPROVE / REJECT / REQUEST-CHANGES + rationale. No code edits.
Governance Phase 7 only, sporadic. Fires on (a) task introduced architectural changes OR (b) Phase-1 post-implementation-governance: yes. Default = skip. Final coherence check vs architecture invariants + ASR utility tree. Continuous PR-time governance RETIRED.

Phase 4 / 5 / 6 — categorical refusal (#182). SA is NOT dispatched during implementation phases. Engineer-surfaced architectural-delta needs route through team-lead’s gate per core/roles/team-lead.md § Engineer-surfaced architectural-delta gate — user picks defer to next design cycle OR stop current task and re-enter Phase 1–2 (Phase 3 design review re-passes; original task resumes Phase 4 against the new contract).

Implementation rendering — forbidden in every SA artefact (#182). Architecture docs · ADRs · requirements register · ASR utility tree · diagrams MUST NOT contain adopter function / method / member identifiers · file paths into the working tree · line numbers · commit SHAs · handler-body code snippets · “how to wire it” prescriptions. SA’s ## Verification log carries SA-artefact content self-lint: PASS / <N findings> per touched artefact. ADRs cite architectural mechanisms + rationale rooted in NFR / constraint, never code sites.

Greenfield vs delta — resolved at Phase 1. Greenfield (no architecture doc) → SA authors a complete architecture doc + initial ADRs. Delta (existing doc) → SA produces ADR/CR proposals + ASR amendments; never rewrites the doc wholesale.

Two-file register split (ASRs are the outcome of requirements, not the same level):

Architect-to-architect — single-architect framework default. Multi-architect projects populate optional local/bindings.md § Architects slot.

Full spec: core/roles/solution-architect.md. Migration: migrations/classical-architect.md.

Change governance gating + opt-out (D45)

Pre-D45, CR / ADR authorship was unconditional once team-lead / SA judged the trigger condition met. Adopters whose source-of-truth for requirement scope is GitHub issues (issue body = the requirement record) had no way to suppress redundant CR drafting; adopters making code changes with no architectural delta had no way to suppress redundant ADR drafting. D45 adds a pre-authorship intercept gate on both surfaces.

Five-key gate (local/framework.config.yaml § change-governance):

change-governance:
  cr:
    enabled: true                       # set false → skip CR authorship
    skip-when-issue-source: true        # issue-sourced task → issue IS the requirement record
  adr:
    enabled: true                       # set false → skip ADR authorship
    require-architectural-delta: true   # no delta heuristic → skip ADR
  prompt-before-create: non-trivial     # always | never | non-trivial

Architectural-delta heuristic — ADR gate fires when the proposal touches ≥ 1 of: component boundaries · wire contracts · NFR-bearing claims · architecture invariants · stack / topology / infrastructure. SA judgment retained for borderline cases (refactor implying invariant shift · wire-shape breaking-vs-additive · NFR-adjacent threshold).

Non-trivial heuristic (drives prompt-before-create: non-trivial) — ≥ 2 architectural-delta triggers OR local/requirements.md register-diff non-empty.

Per-task prefixes override config at dispatch time (precedence: prefix > config > default):

Prefix Effect
cr: Force CR authorship
nocr: Skip CR authorship
adr: Force ADR authorship
noadr: Skip ADR authorship

Combine freely with auto: · branch: / wt: / commit: · model:<tier> · notrack:. Example — auto: branch: nocr: bump retry policy (auto-mode, Mode 1, skip CR).

Skip-reason logging — when the gate skips, ## Decisions made carries one row (CR skipped — skip-reason: <enum> / ADR skipped — skip-reason: <enum>). Fixed enum — config-disabled · issue-source-skip (CR only) · no-architectural-delta (ADR only) · prefix-override · user-declined.

Adopter benefit — issue-as-CR. Pre-D45 team-lead drafted a CR for every issue-sourced scope change, even when the issue body already recorded the change. Post-D45, cr.skip-when-issue-source: true (new default per issue #121) suppresses the redundant CR; the issue body remains the requirement record; PR Closes #<N> preserves traceability.

Auto-mode interactionprompt-before-create: always OR non-trivial heuristic firing under auto-mode forces interactive pause per core/protocols/automatic-mode.md § Forced-interactive triggers. The gate is never silently elided.

Full spec: core/roles/team-lead.md § CR-gate · core/roles/solution-architect.md § ADR-gate · core/process.md § Change governance. Migration: migrations/change-governance-opt-out.md.

Index protocol

local/index/ holds lightweight per-class summaries of the project’s knowledge:

Category Examples
Documentation architecture.idx, architecture-fr.idx, api-matrix.yaml, ui-states.yaml, constraints.yaml, adr-index.idx, cr-index.idx, scenario-index.idx, glossary.idx, mockup-index.idx
Code / config stack.yaml, topology.yaml, commands.yaml, conventions.yaml, runtime-facts.yaml, repo-map.idx

Key invariants:

Full spec: core/protocols/index-protocol.md.

Hot-spec frontmatter (D47)

Every hot-spec file in core/ (the files cardinals load at dispatch time) carries a YAML frontmatter block at the top declaring its load contract:

---
audience: <role | all-cardinals | team-lead-only>
load: always | on-demand
triggers: [keyword1, keyword2]                # required when load == on-demand
cap-bytes: <N>                                # explicit per-file byte budget
reads-before-applying: [path1, path2]         # explicit content-dependency chain; [] if none
---

Scope. core/process.md · core/process/*.md · core/protocols/*.md · core/roles/*.md · core/roles/*.details.md.

Excluded. core/templates/*.md (concrete output shapes) · core/skills/ginee-*/SKILL.md (already use AgentSkills frontmatter) · local/roles/*.md (adopter-owned per D37).

Adopter impact. None — /ginee-update lands the frontmatter wholesale. Adopters writing custom roles under local/roles/ MAY adopt the same format but are not required to.

Why. Eliminates the per-dispatch inference cost — cardinals know from the file’s head whether to load it, when its rules apply, and which other specs to consult first. Compounds across every adopter dispatch.

Validator. scripts/context-economy-check.ps1 fails CI on missing frontmatter; same Optimized-By: ai-engineer trailer-bypass machinery as the existing context-economy gate (D21) + per-class doc-size caps (D44).

Full spec: core/protocols/hot-spec-format.md. Migration: migrations/hot-spec-frontmatter.md.

Delivery modes

PM resolves one of three delivery modes per task — picked by precedence:

  1. Per-task prefix: branch: / wt: / commit: at start of task description.
  2. Per-task Phase-3 user answer.
  3. Adopter default in local/framework.config.yaml § delivery.default-mode.
  4. Framework default — branch for issue / TODO-sourced tasks; wt for freeform.
Mode Phase 4 commits Phase 8 finalize
1. Branch + PR gh issue develop (issue-sourced) or git checkout -b; commits on branch git push -u origin; gh pr create with Closes #<N>
2. Working-tree only No commits PM surfaces git diff; user commits / discards manually
3. Commit-no-push Commits on current branch PM surfaces git log --oneline; user pushes manually

Combinable with auto:auto: branch: fix the deploy logs spam is valid.

Full spec: core/protocols/delivery-modes.md.

GitHub issues + discussions as a task source

ginee picks up GitHub issues with the same Phase 1–8 lifecycle as TODO lines and freeform requests:

Slash commands work on tier-1 clients (Claude Code, Copilot CLI). Natural-language phrasings (File a bug titled X, Pick up #42, Triage) also match the skill description. Tier-2/3 fallback uses act as team-lead and ....

PRs reference the issue with Fixes #<N> / Closes #<N> — GitHub auto-closes on merge.

Full spec: core/protocols/github-integration.md.

Sub-issue dispatch — cross-session traceability + time-tracking (D39)

Pre-D39, every team-lead → cardinal dispatch lived only in the chat transcript — end the session, lose the state. D39 lands each cardinal dispatch as a GitHub sub-issue under the parent task issue. Cross-session resume now reads parent + open sub-issues; no transcript replay.

Concern Pre-D39 After D39
Cross-session resume Replay transcript + grep commits Read parent + open sub-issues
Mid-dispatch hand-off One-shot hand-off note Live sub-issue thread
Parallel-cardinal traceability Buried in synthesis turn One sub-issue per role, queryable
Effort attribution Not surfaced anywhere Per-comment time: + per-cardinal rollup

Scope. Issue-sourced tasks only. TODO / freeform fall back to in-context dispatch (no parent issue to anchor sub-issues under).

Lifecycle per dispatch.

  1. team-lead drafts the dispatch contract (scope · acceptance · spec links · phase · estimate).
  2. Creates a sub-issue under the parent — title [<phase>:<cardinal>] <task>; body = contract per core/templates/sub-issue-dispatch.md; labels ginee:role:<cardinal> + ginee:phase:<N> + inherited value:* / complexity:*.
  3. Cardinal executes; progress comments thread on the sub-issue — each carrying time: <N>m (since last comment) + cumulative: <N>m (since dispatch start).
  4. D29 phase-report return doubles as the closing comment with mandatory ## Time spent section. team-lead closes the sub-issue.
  5. Parent’s <!-- ginee:dispatch-map --> sticky aggregates per-cardinal time across all sub-issues.

Stop-state. Status: In-progress posts as a progress comment; sub-issue stays open. Next pickup reads the comment trail and resumes from where the cardinal stopped.

Assignee precedence. Non-empty human assignee on a sub-issue overrules the ginee:role:<cardinal> tag — cardinal dispatch suspended until the assignee clears. Rationale — GitHub’s assignee column means a human is responsible; cardinals are not GitHub users; when both exist, the human wins.

Opt-out (stop at first match).

  1. Per-task notrack: prefix (combinable with auto: / branch: / etc.).
  2. ginee:track:off label on the parent issue (per-issue lifetime).
  3. local/framework.config.yaml § dispatch.tracking: in-context (repo-wide).
  4. Framework default — sub-issues when github.repo is configured.

Time-tracking. Cardinal-reported perceived effort (not session wall-clock). Granularity — minutes. Format time: <N>m (under 60m) or time: <H>h <M>m (60m+).

Sub-issue pickup fast-path. /ginee-pick-up #<N> against a sub-issue with a populated routing artefact (single ginee:role:<cardinal> label + dispatch-contract body) dispatches the named cardinal directly — @team-lead re-route skipped. Re-entry through @team-lead triggers on role-label gap · ## Open issues non-empty · ## Hand-off set · Status: In-progress · cross-domain bug. Parent-issue pickups unchanged. Full spec — migrations/sub-issue-fast-path.md.

Full spec: migrations/sub-issue-dispatch.md.

Triage scoring (D23)

/ginee-triage ranks ready work by score = value / complexity (default WSJF cost-of-delay over job-size) instead of age. Two axes, same scale — ATAM utility-tree H/M/L (H=3, M=2, L=1).

Axis Source-of-truth Set by
value label value:high|medium|low Reporter (never auto-guessed)
complexity label complexity:high|medium|low Reporter, OR solution-architect auto-estimate on pickup (ATAM signals: touched-file count, role count, novel concepts, pattern reuse)

9-cell matrix (rounded): HL = 3.00 quick-win at the top; HH = MM = LL = 1.00; LH = 0.33 at the bottom. Adopter override: local/framework.config.yaml § triage.scoring-formula accepts value-over-complexity (default) / value-only / value-minus-complexity.

TODO equivalent — inline marker after the glyph (case-insensitive):

☐ [v:H c:L] Bump retry policy             # quick-win, scores 3.00
☐ [v:H] Investigate flaky pipeline        # complexity unknown — imputed L
☐ Refactor logger                          # unscored — sorts last

Sticky comment<!-- ginee:score v=1 -->, one per issue, updated in place on ginee-driven label changes. Hybrid topology: live sticky state + immutable audit comments (ginee:complexity-estimate / ginee:value-prompt / ginee:score-recompute).

Manual override@team-lead recompute score #<N> re-reads current labels (catches manual gh issue edit between sessions) and refreshes the sticky.

Pickup is never gated on score — score informs order, not eligibility. Full spec: core/protocols/triage-scoring.md.

Review-comment ingestion (D24)

/ginee-address-review #<PR> (or @team-lead address-review #<PR>) covers the interval between Phase 7 (internal SA review) and Phase 8 (user accept) when a PR is exposed to external review (peer maintainers, OSS contributors, user-as-reviewer). Skill + command parity — both run the same procedure under the same governance.

Step Action
1 Resolve <PR>; verify checked-out branch == PR head; fetch pulls/{N}/comments + /reviews
2 Deduplicate by thread-id; skip resolved + already-marked threads (unless newer reviewer comment landed)
3 Build routing records per local/bindings.md § Source-of-truth ownership; fallback team-lead; ambiguous → surface-closest role
4 Surface consolidated plan table — # / thread / file:line / role / proposed action / action-type
5 Dispatch specialists in parallel; each returns fix-track patch OR reply-track text + marker
6 Squash fix patches into one cycle commit + push; post per-thread replies
7 Post one sticky cycle summary — Review cycle N: M remarks addressed (K code, M-K reply). HEAD: <sha>.

Forced-interactive gate — plan-table approval is non-bypassable; applies even in auto: mode per core/protocols/automatic-mode.md § Forced-interactive triggers. No exception for “trivial” remarks.

Lossless coverage — every plan-table thread MUST end the cycle as fix OR reply. No silent drops.

Idempotency — markers <!-- ginee:review-reply r=<thread-id> --> (per-thread) + <!-- ginee:review-cycle n=<N> --> (sticky). Re-invocation covers net-new + revisited threads only; cycle ordinal increments; prior stickies preserved (immutable log).

Explicit invocation only — no extension of the D20 CI-watch loop; auto-detection of new review comments is out-of-scope.

Full spec: core/protocols/github-integration.md § Review-comment ingestion.

Doc-authoring protocol (D22 + D26)

When ginee authors markdown — adopter docs (D22) OR ginee-authored GitHub artefacts (D26) — core/process.md § Documentation style — structure over prose is binding, not aspirational. Six mandatory checks (D48 added RFC 2119 binding-strength signal — MUST · MUST NOT · SHOULD · SHOULD NOT · MAY — instead of always / never / binding / mandatory / required as rule modifiers); structure-default-by-class shape map.

Scope:

Surface Authored by In scope since
Architecture doc · ADRs · CRs · READMEs · runbooks · scenarios · API docs adopter roles D22
GitHub issue bodies authored via ginee-file-* skills team-lead (you approve) D26
Framework-authored GitHub comments — Phase-transition · sticky ginee:score / ginee:review-cycle · audit comments · per-thread review-replies team-lead + specialists D26

Default-shape map:

Doc class Default shape
Component / endpoint / service inventory Table
Step-by-step procedure / runbook Numbered list
ADR rationale (decision + context + consequences) Definition lines + bullets
Scenario / acceptance criteria Given-When-Then bullets
Glossary / API matrix Table
Rules with > 2 conditions Parent bullet + sub-bullets — one rule per line

Lint covers every section, including Summary (D26) — no section-by-length exemption. A one-sentence Summary still trips the mandatory checks if it packs a comma-separated inventory into a parenthetical clause.

Enforcement — two paths:

Reporter-authored content (your own issues, your own comments) — never auto-edited; D14 forbidden upheld. ginee-pick-up MAY surface a polite restructure advisory but never rewrites your text.

Scope (out-of-scope):

Full spec: core/protocols/doc-authoring-protocol.md. Examples (9 bad/good pairs): core/protocols/doc-authoring-examples.md.

Changelog + release-notes protocol (D40)

Extends the doc-authoring scope to the three release-surface files. Closes a recurring drift mode — pre-D40, release-notes sidecars repeatedly drifted into framework-dev voice + oversized bullets, requiring multi-pass rewrites after publish (the v0.12.0 sidecar took four passes to converge).

Three surfaces, three voices, three caps:

Surface Purpose Voice Bullet cap
migrations/D<N>-*.md Full spec — schema · checks · rollback · file list Framework-dev (precise jargon OK) None — structured tables / lists
docs/CHANGELOG.md Verbose record per Keep-a-Changelog Framework-dev OK in sub-bullets; lead-in ≤ 25 words Lead-in ≤ 25 words + sub-bullets
.github/release-notes/v*.md Marketing on the GH Release page User-value voice — adopter-visible benefit at line start ≤ 20 words per bullet + (D<N>) tag

Voice rule — sidecar. Lead with the adopter-visible verb / outcome — /ginee-update works again” not “Step 1 no longer requires installer scripts inside .agents/ginee/; “Lower LLM bills” not “Three vendor-neutral tiers declared as role-kernel default-tier:.

5 mandatory checks before publishing a sidecar — per-bullet word cap · user-value voice · (D<N>) tag suffix · no implementation boilerplate (file-update lists / “purely additive” stat blocks belong in the migration) · migration link in footer.

Enforcement — LLM self-review at draft time; one-line orchestrator advisory on violation; never auto-rewrites. Same machinery as D22 / D26 / D29 / D30.

D34 carve-out — sidecar D-tags stay bare ((D31)) rather than slug-glued (D31-model-tier); the slug form is required only in framework specs · adopter docs · cardinal returns. Sidecars carry the spec link in the footer.

Scope (out-of-scope) — retroactive rewrite of pre-D40 sidecars (forward-only); external markdown linter / CI gate (self-lint only); translation / localization; style / tone / branding beyond voice.

Adopter impact — none (framework-internal authoring rule; affects ginee maintainers writing release artefacts, not adopters).

Full spec: core/protocols/changelog-protocol.md + migrations/changelog-protocol.md.

Blueprint-diff gate for visual source-of-truth (D41)

Phase 4 entry precondition for any dispatch touching the configured visual source-of-truth artefact (mockup · Figma · image baseline · video · adopter-supplied). Closes the adopter-incident class where Phase 4 silently rewrote chrome elements while Phase 5/6 geometry oracles ran green.

Procedure — dispatching role runs the protocol as first step of any Phase 4 dispatch that touches the configured visual-source-of-truth.path:

  1. Resolve config from local/framework.config.yaml § visual-source-of-truth (defaults derive from existing mockup: key when absent).
  2. Compute the diff working-copy vs blueprint-ref (default origin/main) — per-type tool selection.
  3. Classify each delta as Expected (inside issue scope) · Unexpected (outside issue scope) · Pre-existing (present before dispatch).
  4. Surface to team-lead.
  5. Gate Phase 4 edits — all-Expected/Pre-existing → edits proceed; any Unexpected → forced-interactive gate (auto-mode does NOT elide).

Per-type diff tools:

type Tool
html-mockup git diff <blueprint-ref> -- <path> (built-in; universal)
figma File-comparison URL or REST GET /v1/files/<key>/versions
image Adopter-supplied perceptual diff — pixelmatch · odiff · Resemble.js · Playwright snapshot-compare
video Manual review checkpoint
other Adopter-supplied tool from local/index/commands.yaml § commands.visual-diff

4 mandatory checks before edits begin — config resolved · diff computed · classification complete · surface logged in ## Verification log. LLM self-review at draft time; one-line orchestrator advisory on violation; never auto-rewrites.

Adopter impact — adopters with mockup: configured get the gate on next dispatch with zero local/framework.config.yaml edits (defaults derived). Adopters with no mockup configured — protocol auto-skips. Override the defaults to point at a Figma URL · release-tag blueprint · frozen snapshot · adopter-supplied diff tool.

Full spec: core/protocols/blueprint-diff-protocol.md + migrations/blueprint-diff-gate.md.

Subagent-return schema (D29)

Every cardinal-dispatch return is schema-bound per core/templates/phase-report.md — same machinery as the D22 / D26 doc-authoring protocol, scoped to the subagent-return surface. Goal: cut ~70% off subagent-return bloat (today’s largest orchestration-thread contributor).

Mandatory sections (empty case: (none)):

Section Cardinality Default shape
## Files touched required Table — path · Δ lines · purpose
## Decisions made required Bullets — <imperative> — cite (≤ 80 chars / bullet)
## Verification log required Table — command · outcome
## Open issues required Bullets — <issue> — <owner>
## Next dispatch needed required One-liner — <role> · <surface> · <reason>
## Source reads (this dispatch) required (else (none)) Table — Path · Justification · Index entry consulted
## Hand-off conditional — forced handoff per core/protocols/cross-agent-handoff.md core/templates/hand-off-note.md shape
## Stop-state conditional — Status: In-progress Done / In-progress / Not-started bullets
## Notes optional — narrative escape hatch Free prose · ≤ 200 words · ≤ 5-line code-snippet carve-out

7 mandatory checks before report-as-done — 6 from D22 / D26 / D48 + no narrative preamble (first non-Status line must be a ## section header). ## Source reads joins as required-with-empty-case (matching ## Hand-off / ## Stop-state precedent) — count adjusted to reflect D48’s RFC 2119 binding-strength check.

Forbidden patterns — narrative preamble · restated dispatch context · code snippets outside the Notes carve-out · verbose rationale outside ## Notes · parenthetical comma-soup.

Enforcement. LLM self-review against the schema before returning. No external linter. Orchestrator surfaces a one-line advisory on violations and consumes anyway. Single carve-out — when raw source paths appear in ## Files touched AND ## Source reads (this dispatch) is missing or (none), orchestrator re-dispatches for the justification cycle. Never auto-rewrites (analogous to D14 reporter-content forbidden).

Index-first read order. Cardinals consult local/index/ summaries + role-kernel Source of truth § always rows before any raw source read; raw reads are fallback when an index entry’s anchor points at a fragment needed verbatim OR the role authors new content in that source. Every raw read records a one-line justification in ## Source reads (this dispatch). Full bedrock rule: core/protocols/index-protocol.md § Read order.

Full schema: core/templates/phase-report.md. Bad/good example: core/protocols/doc-authoring-examples.md § 10. Migration: migrations/strict-subagent-return-schema.md.

Output-schema sidecars (D49). Five other high-frequency structured outputs the framework produces — dispatch prompts · sticky ginee:score · audit comments · sub-issue bodies + cadence · review-cycle replies + sticky — each get a sidecar under core/protocols/ following the phase-report meta-template. See dispatch-prompt-schema.md · score-comment-schema.md · audit-comment-schema.md · sub-issue-dispatch-schema.md · review-cycle-schema.md.

Adopt-vs-build option lists (D30)

Every Phase 2 design proposal and every iteration-protocol Propose step (Phase 4–7 sub-tasks > 15 min where adopt-vs-build is a live axis) MUST surface ≥ 1 adopt-existing-solution candidate or an explicit (none viable — <reason>) cite. Stops the LLM-default failure mode: authoring novel implementations when no rule binds the proposer to look outward first.

Option-list schema (4 candidate types):

Candidate type Required fields
adopt name · version · source link · license · one-line fit rationale
build scope · one-line rationale why adoption was rejected
hybrid adopt portion (full citation) + build portion + boundary rationale
(none viable — <reason>) one-line reason — empty-research escape hatch

Floor. Hard: ≥ 1 adopt candidate OR (none viable). Soft: encourage 2–3 adopt candidates for non-trivial scope.

5 mandatory checks before surfacing — adopt floor present · citations complete · tagging explicit (adopt / build / hybrid — no silent mixing) · empty research documented · fit rationale concrete (not hand-waved).

License + supply-chain stance. Framework requires the citation but expresses no opinion on which licenses pass. Adopters author a local/ policy file if gating is wanted.

Enforcement. LLM self-review before surfacing the proposal. No external linter. Orchestrator surfaces a one-line advisory on violations but never auto-rewrites (analogous to D29).

Full spec: core/protocols/options-protocol.md. Bad/good example: core/protocols/doc-authoring-examples.md § 11. Migration: migrations/adopt-existing-solution.md.

Per-role + per-task model tier (D31)

Routes reasoning-heavy roles to capable models and execution-heavy roles to cheaper ones. Tier names are vendor-neutral in core/; concrete model IDs live only in the adapter layer.

Tier Use Default model (Claude adapter) Default for
reasoning Orchestration · synthesis · architectural calls claude-opus-4-7 team-lead · solution-architect
standard Implementation · tests · doc-shape · lint fixes claude-sonnet-4-6 ai-engineer · backend-engineer · frontend-engineer · devops-engineer · qa-engineer
fast Mechanical · label ops · sticky updates claude-haiku-4-5-20251001 (opt-in for adopter-defined mechanical work)

Resolution order — stop at first match: (1) per-task prefix model:<tier> in the dispatch line (combinable with auto: / branch: / wt: / commit:); (2) Phase-3 user answer; (3) local/framework.config.yaml § model-tier.per-role.<role>; (4) core/roles/<role>.md frontmatter default-tier:.

Adapter behaviour. The Claude adapter writes model: <id> into each .claude/agents/<role>.md frontmatter from the resolved tier (pre-resolved default at install; rewritten when local/framework.config.yaml § model-tier carries overrides). Cursor / Copilot CLI / Codex / generic emit a one-line install warning — those surfaces don’t expose programmatic per-role model selection today; the per-task prefix is a documented user-side hint.

Backward compatibility. Purely additive. Absent model-tier: → framework defaults apply silently. Existing dispatches unaffected until adopter sets a tier or uses the prefix.

Full spec: migrations/model-tier.md.

Skill-runner vs team-lead (D28)

ginee skills (/ginee-pick-up, /ginee-address-review, /ginee-triage, /ginee-promote-discussion, …) run inside a thin skill-runner — the Claude main thread, Cursor main loop, Copilot CLI main loop, or AGENTS.md-driven shell that executes the skill body. The skill-runner is not a role and not an orchestrator.

Skill-runner does Skill-runner does not
Parse prompt + identify task source Draft a Phase 1–8 dispatch plan
Label / sticky / audit-comment ops Synthesize parallel specialist returns
Branch ops per resolved delivery mode Author lifecycle gate text (Phase 3 / 7 / 8)
The skill’s one named first-batch dispatch Re-dispatch specialists after the first batch
Report mechanical result to the user Reconcile routing on engineer pushback
  Pick defaults (“I’ll pick option 1 if you don’t redirect”)
  Read local/bindings.md to settle a routing question

Hand-back rule. Every ginee-* skill dispatches @team-lead after its first mechanical batch. From there every orchestration decision flows through team-lead. If a routing or governance question arises mid-flight, the skill-runner dispatches @team-lead to answer — it never answers by reading project files itself.

Why the rule. Pre-D28 the skill-runner often drifted into orchestration on long sessions (issue #71): plan drafting in the main thread, synthesizing parallel returns, proposing default-selection options. The boundary is now structural — every skill carries an explicit hand-back step.

ginee-iterate — review-cycle relay along the boundary. On a live cardinal task, each user reply SendMessages the warm cardinal verbatim instead of editing from the main thread — the warm-reuse path (migrations/warm-specialist-reuse.md · migrations/warm-reuse-claude-plumbing.md · migrations/warm-cardinal-default.md) stays intact across the cycle. Skill-runner detects · forwards · passes return through; hand-back to @team-lead on ## Open issues / ## Hand-off / stop-state. Full spec: core/skills/ginee-iterate/SKILL.md · migration: migrations/ginee-iterate-skill.md.

Full spec: core/process.md § Skill-runner — surface boundary. Migration: migrations/skill-runner-boundary.md.

Framework self-update

/ginee-update [<tag|branch|sha>] drives the install.{ps1,sh} --update-only flow under explicit user approval — never auto-runs. The installer lives at upstream, not inside .agents/ginee/ (per D27); the skill fetches install.{ps1,sh} from raw.githubusercontent.com/<github.framework-repo>/<target-ref>/ to a temp dir, then runs it with the detected adapter + project root. team-lead resolves the target ref (latest release / explicit tag / branch / SHA), surfaces the update plan (current core/VERSION → target ref + installer command + preserved/replaced trees), waits for yes, then runs the installer per platform. Post-update report: VERSION delta + CHANGELOG range + new migrations/*.md files with Action required excerpts + local/index/manifest.yaml SHA drift offer.

Full spec: core/skills/ginee-update/SKILL.md.

What ginee doesn’t do

Next