BeWith AI Engineering Strategy
Author: Ariel Benesh, bewith-dev engineering
Status: Authoritative reference for the platform's design, implemented as a working POC and in active use. Formal CTO sign-off (Aviad) and org-wide rollout are still pending.
Purpose: Authoritative reference for how bewith-dev will build production software with Claude-based AI assistance. Suitable for CTO presentation, NotebookLM ingestion (presentation + podcast), new-engineer onboarding, and architectural decision context.
Implementation notesโ
How the platform is actually built, and why. Each note records a deliberate decision taken during the build โ the pragmatic shape the implementation settled on, and the reason behind it. The strategic intent (the principles, the autonomy model, the SDLC) is unchanged; these notes only describe how it was realised.
Repository structure flattened. The original plan envisioned a three-layer top-level layout (governance/, knowledge/, templates/) inside one repo. The implementation is flat โ .claude/, policies/, autonomy/, events/, configs/, templates/, docs/, scripts/ all sit directly under the repo root. The governance/knowledge/templates separation lives logically (in CODEOWNERS and review routing) but not in directory paths. Reason: the nested form created confusion about whether governance/CLAUDE.md or .claude/ was the source, and Docusaurus multi-instance docs work cleaner against a flat layout. See ยง5 and ยง6.1 for the current shape.
contracts/ removed entirely. The original plan listed contracts/api/ + contracts/zod/ as platform-level shared contracts. Removed because contracts (OpenAPI specs, Zod schemas, generated bindings) are domain artifacts, not meta-governance โ they belong inside each consumer service, not in the bewith engineering platform. The convention for handling contract changes is preserved in policies/api-contract-change.yaml for downstream repos to adopt. See [[methodology-deterministic-ai]] principle 6 (Knowledge โ Governance) โ contracts are neither.
CI workflows live in .github/workflows/, not configs/github-workflows/. The original plan placed reusable CI under configs/github-workflows/. GitHub Actions' uses: resolver requires reusable workflows to live under .github/workflows/ of the calling-out repo โ it cannot resolve them from configs/. The deviation is a constraint, not a preference. A pointer file at configs/github-workflows/README.md documents the MVP catalog and links back to .github/workflows/.
MVP CI cut: 2 built, the rest deferred/dropped. The original plan lists 7 platform CI workflows in ยง16.2. Current state:
- Built:
clickup-commit-check.yml(reusable),governance-serialize.yml(platform-only). Plus shared validators inscripts/checks/. (governance-version-check.ymlwas built then removed 2026-05-27 with the rest of thegovernance.lockmodel โ see ยง6.4.) - DROPPED โ won't build:
cross-impact-check.yml(git's merge mechanism + CODEOWNERS auto-assign cover the "awareness" use case without CI noise) andcontract-impact-analysis.yml(contracts are domain artifacts; see above). - DEFERRED with re-trigger conditions:
test-quality-check.yml(waiting for the first consumer repo with a real test suite),lease-cleanup.yml(waiting for the lease infrastructure that owns the store/schema/API),ai-pr-review.yml(waiting for thecode-revieweragent and a cloud-bootstrap mechanism for materializing the platform into a CI session).
Lease infrastructure deferred. The original plan designs a GitHub-Issue-based lease store with 30-minute leases, 10-minute heartbeats, and a lease-cleanup.yml scheduled workflow. None of it is built โ the store, schema, claim API, heartbeat, and cleanup all wait for a dedicated implementation pass. Until then, lease-related sections of the original plan read as design intent, not current behavior. The claim-race problem is handled meanwhile by the ClickUp-assignee-is-owner convention (still in force) and small team size.
commit-cu-check is opt-in, not always-on. The original plan implies CU-id is required on every commit message. Implementation switched to opt-in via REQUIRE_CU_ID in git-hooks/config.env โ default off โ because the platform repo itself does not always have a 1:1 ClickUp task per commit. The PR-title gate in clickup-commit-check.yml remains the canonical place for the hard CU-id check; commit-level is a softer per-repo opt-in.
branch-name-check is dual-mode. The original plan specifies a single regex with mandatory _CU-{id}. The implemented hook reads the same REQUIRE_CU_ID flag: when on, the suffix is mandatory and validated by the shared scripts/checks/check-cu-id.sh (โฅ6 chars, โฅ1 digit, โฅ1 letter); when off, the suffix is optional but if present is still validated (no placeholder workarounds like _CU-pending). The docs branch type was added to the list. Multi-actor prefixes (cc-ariel/...) are not currently enforced. See ยง6.7 for the current regex and rule.
Consumption model: Claude Code plugin, not per-repo materialization. The original plan describes a build step that materializes .claude/effective/ inside each consumer repo by syncing the pinned platform + applying overlay. Implementation skipped that entirely. The platform ships as a Claude Code plugin published from this repo (.claude-plugin/plugin.json + marketplace.json). Developers install once via the sandbox CLI's install-developer command (three steps: GITHUB_TOKEN โ /plugin install bewith โ git config --global core.hooksPath ~/.claude/plugins/cache/bewith/git-hooks). Every Claude Code session globally then sees the platform's agents, skills, commands, hooks; every git operation in any repo runs through the platform's hooks. New consumer repos get a thin scaffold (CLAUDE.md + .github/copilot-instructions.md) via the idempotent install-to-consumer.sh. No per-repo lock file, no per-session build step. See consumption-model.md for the full federation flow.
Lock file dropped. The original plan introduced governance.lock for per-consumer version pinning. An interim 2026-05-26 design carried it as a governance.lock.json CI contract. 2026-05-27 decision: removed entirely. Reasons: (a) the plugin's version field + each consumer's reusable-workflow uses: โฆ@v0.1.0 ref together provide the same pinning at less complexity, (b) rules are not expected to change dramatically enough to justify per-repo audit-trail files, (c) install-to-consumer.sh becomes cleaner. The check workflow governance-version-check.yml and scripts/checks/check-governance-lock.sh were deleted. If audit needs ever require per-repo version recording beyond the CI workflow ref, the lock comes back.
.yanked.json dropped. Removed together with the lock contract. Yanking a platform release is now handled the standard way: tag the marketplace catalog entry for that version as withdrawn, or bump the plugin to a fix release and document the recommended upgrade in the GitHub release notes. The previous .yanked.json HEAD-level manifest was tied to the lock validator and has no role in the plugin model.
Policy Engine runtime is out of scope for this repo. The original plan describes "the engine" as if it lives here. Implementation: the policies live here as YAML + JSON Schema validator. The engine that evaluates triggers at step 4 of /continue is downstream โ it belongs in whatever Claude skill or CLI ends up consuming the policies. Policies in this repo are a normative library, not a running service.
dangerous-patterns is JSON, not YAML. The original plan names it .yaml. The actual file is .json. Reason: validator scripts already use JSON-loading helpers and adding a YAML dependency would have broken Docusaurus's strict ESM module resolution. The same pattern repeats for any per-file machine-readable config โ JSON unless there's a specific YAML reason.
autonomy/schema.json added. Not in the original plan. A JSON Schema draft-07 validates ~/.claude/user-overrides.yaml against the 6 known configurable gates. Hard Floor and never_ask items remain unoverridable by schema, not just by convention.
Hooks reorganized: Claude Code vs git, separate directories. The original plan grouped every hook under .claude/hooks/. The implementation splits them by enforcement mechanism: .claude/hooks/ holds Claude Code hooks (PreToolUse + SessionStart โ block-edit-on-master, block-dangerous-{git,bash}, mcp-availability-check, active-context-validate). git-hooks/ (top-level) holds git hooks (pre-commit, commit-msg, pre-push orchestrators + their sub-hooks). The Claude Code hooks are declared via .claude/hooks/hooks.json so they fire user-globally; the git hooks are reached via a machine-global core.hooksPath that the plugin's git-hooks-sync SessionStart hook points at the plugin's current git-hooks/ (self-healing across always-latest updates; no-op on non-bewith repos) so they fire on every bewith repo on the developer's machine. Two different enforcement layers, two different declaration paths.
branch-name-check + file-size-check mirrored in CI. Added 2026-05-27 as reusable workflows in .github/workflows/. Reason: Copilot, Claude mobile, and manual developers do not run our local git hooks โ CI is the mandatory gate that catches them. Every git-hook check that can be expressed against a PR now has an *.yml reusable equivalent.
.github/copilot-instructions.md template added. GitHub Copilot reads this file automatically per the official docs. The template lives in templates/consumer-repo/ and is a pointer to CLAUDE.md + the BeWith platform; it never duplicates content. Same "references, not copies" rule.
Agent template revised from 9 sections to 7. The original plan prescribed a 9-section agent body. The current implementation uses a lighter 7-section body that follows Anthropic's canonical sub-agent pattern (Role โ When invoked โ Checklist โ Output format) and keeps two BeWith-specific additions (Handoff points, Cross-references, optional Anti-patterns). Frontmatter now uses proper tools (allowlist), model: inherit, and "use proactively" framing in descriptions per Anthropic's documented auto-routing patterns. See docs/templates/agent-template.md and ยง12.2 below.
The methodology prose is the core. Sections that describe the methodology โ the problem (ยง1), the principles (ยง4), the autonomy criteria (ยง10.1.1), the testing strategy (ยง17), the adoption story (ยง22), the day-to-day walkthrough (ยง23) โ carry the strategic vision. These implementation notes only record how the build realised it.
Executive Summaryโ
English. bewith-dev today uses ad-hoc AI tooling without a unifying discipline. The result is the same five failure modes every solo developer hits โ amnesia, non-determinism, test neglect, duplication, doc drift โ multiplied by team and scale problems: claim races, governance drift across 44 repositories, contract changes that break consumers silently. The proposal is Deterministic AI Engineering: a methodology that treats the stochastic LLM as a teammate operating inside hard tooling gates. We move every load-bearing rule out of prompts and into git hooks, CI workflows, a Policy Engine, and shared YAML. We separate "how we work" from "what we know," version both, and let each consumer repo pin to a specific release. Manual developers get the same safety floor as AI-driven ones โ the standard is organizational, not AI-specific. Token usage stays flat as the platform grows because the AI loads only what the current task requires. The end state is an environment where Claude can drive an end-to-end ticket โ from ClickUp through implementation, tests, PR, review, merge, and deploy โ under tight gates that humans audit, not gates the model enforces on itself.
ืขืืจืืช. ืืืื bewith-dev ืืฉืชืืฉืช ืืืื AI ืื-ืืืง ืืื ืืฉืืขืช ืืืืื. ืืชืืฆืื: ืืืฉืช ืืฉืื ืึพAI ืฉืืคืชื ืืืื ืคืืืฉ (ืืืืื ืืงืฉืจ, ืืึพืืืจืืื ืืื, ืืื ืืช ืืกืืื, ืืคืืืืช ืงืื, ืกืืืคืช ืชืืขืื), ืืคืื ืืขืืืช ืฆืืืช ืืงื ืึพืืืื (ืชืคืืกืช ืืฉืืืืช ืืืงืืื, ืกืืืคืช governance ืืื 44 ืจืืคืื, ืฉืื ืืื ืืืื ืฉ"ืฉืืืจืื ืืฉืงื"). ืืืฆืขื: Deterministic AI Engineering โ ืืชืืืืืืืื ืฉืืชืืืืกืช ืืืืื ืืกืืืืกืื ืืืืจ ืฆืืืช ืฉืขืืื ืืชืื ืฉืขืจืื ืืื ืืื ื ืืงืฉืื. ืื ืื ื ืืืฆืืืื ืื ืืืง ื ืืฉืึพืืฉืงื ืืืคืจืืืคื ืื git hooks, CI workflows, Policy Engine ืึพYAML ืืฉืืชืฃ. ืื ืื ื ืืคืจืืืื "ืืื ืขืืืืื" ื"ืื ืืืืขืื", ืื ืืืื ืืจืกืืืช ืืฉื ืืื, ืื ืืชื ืื ืืื ืจืืคื consumer ืืืื ืขื ืืืจืกื ืกืคืฆืืคืืช. ืืคืชืืื ืฉืื ืืฉืชืืฉืื ืึพAI ืืงืืืื ืืช ืืืชื ืจืฃ ืืืืืืช โ ืืกืื ืืจื ืืื ืืจืืื ื, ืื ืชืืื ื ืฉื AI. ืฉืืืืฉ ืืืืงื ืื ื ืฉืืจ ืงืืืข ืื ืืืืื ืืืขื ืจืง ืืช ืื ืฉืืืฉืืื ืื ืืืืืช ืืืจืฉืช. ืืกืืฃ ืืืจื, Claude ืืกืืื ืืืขืืืจ ืืฉืืื ืฉืืื ืึพClickUp ืืืกืืื, ืึพPR, ืึพreview, ืืืืืื ืืึพdeploy โ ืชืืช ืฉืขืจืื ืฉืืืื ืืืงืจ, ืื ืฉืขืจืื ืฉืืืืื ืืืืฃ ืขื ืขืฆืื.
Recommendation in One Sentenceโ
bewith-dev adopts Deterministic AI Engineering as its methodology and the AI Governance Stack as its implementation โ a single, versioned repository (bewith-dev/bewith-docs) that turns the non-deterministic LLM into a disciplined, autonomous teammate operating inside hard tooling gates, an explicit Policy Engine, configurable autonomy controls, and shared knowledge that survives model changes, developer turnover, and the chaos of forty-four parallel repositories.
Table of Contentsโ
- The Problem We're Solving
- The Solution at a Glance
- Two Layers: Methodology and Architecture
- Core Principles
- The Single-Repository Architecture
- Repository Structure
- The End-to-End Flow
- The Thirteen-Step Autonomous Loop (
/continue) - The Policy Engine
- Configurable Autonomy
- The Full SDLC โ Flows Claude Will Drive
- The Expert Agents
- Workflows, Commands, and Skills
- State Management
- Ownership and Leases
- Hard Gates: Hooks and CI
- Testing Strategy
- Release Management
- MCP Integrations
- Migration Path
- Onboarding
- Adoption Strategy
- Day-to-Day Developer Experience
- Conventions Live in Git, Not in Confluence
- Source-of-Truth Consolidation Plan
- Extensibility and Governance Evolution
- Manual-Friendly Workflows
- Metrics and Telemetry
- Risks and Mitigations
- Future Work
- Appendices
1. The Problem We're Solvingโ
1.1 The Promise vs. the Realityโ
Every AI coding assistant promises a tireless junior engineer. The reality, at multi-repo, multi-developer, microservice scale, is a stateless code generator with severe behavioral drift โ a model that follows whatever rules happen to land in its current context window, and forgets them the moment the conversation grows long enough.
bewith-dev has been using ad-hoc AI tooling without a unifying discipline. The patterns below have appeared repeatedly. They are not the fault of any specific model โ they are the inevitable outcome of treating a stochastic system as if it were deterministic.
1.2 Failure Modes at the Individual Levelโ
The five failures every solo developer encounters when using AI assistants ad-hoc:
Amnesia and context loss. The AI forgets earlier decisions and project rules ten to twenty messages into a conversation. The same convention is reinvented three different ways across sessions.
Non-determinism. The same prompt produces different outputs at different times. There is no way to predict, audit, or reproduce the AI's behavior.
Test neglect. As the context window fills up, the AI quietly drops testing from its workflow. Coverage that started at 80% in early sessions ends at 30% by the end.
Code duplication. The AI does not read existing code before writing new code. Helper functions get reimplemented. Patterns get reinvented. Two parallel solutions ship to production.
Documentation drift. The AI updates code but not the spec. API documentation, OpenAPI schemas, and architectural decision records fall behind reality. The codebase becomes the only source of truth, and reading it becomes the only way to learn the system.
1.3 Failure Modes at the Team and Scale Levelโ
When multiple developers and multiple repositories are involved, four additional failures emerge:
Claim races. Two AI sessions (whether from two developers or one developer's two parallel sessions) start working on the same ticket within milliseconds of each other. Both produce branches. Both produce PRs. Merge becomes an archaeology project.
State file conflicts. When the AI tries to track session state in shared files, two sessions overwrite each other's progress. Git conflicts appear in files that were supposed to prevent conflicts.
Governance drift. Two repositories drift apart on what "valid TypeScript" or "valid commit message" means. The same rule exists in five places, in three different wordings. The AI follows whichever version it saw most recently. (We have a concrete example today: branch naming is documented two different ways in two different files in AI_GOVERNANCE/, with both files claiming to be the source of truth.)
Schema blast radius. A contract change in one microservice silently breaks every downstream consumer. The change passes its local tests because consumers aren't part of the test suite. Production breaks at 3 AM.
1.4 Why bewith-dev Specifically Suffersโ
The general problems above land hardest at bewith-dev for specific reasons:
Scale. Forty-four active repositories. A platform built on NestJS microservices, Next.js frontends, a legacy Yii2 PHP system, Flutter mobile apps, MongoDB and Aurora data stores, AWS ECS infrastructure, Cognito authentication, SQS workers, and Datadog observability.
Mixed technology. PHP and TypeScript in the same product. Backend services in NestJS, frontends in React, mobile in Flutter, legacy code in Yii2. An AI that "knows JavaScript" is useless when it can't tell whether to consult the PHP rules or the TS rules.
Multi-developer. Multiple engineers working in parallel across the same repos and the same ClickUp board. Coordination cannot be ad-hoc.
Full SDLC scope. The work that an AI assistant should participate in is not just "writing code." It spans idea capture, spec validation, design review, implementation, testing, code review, QA, deployment, monitoring, incident response, and post-mortem. A solution that only addresses the coding step solves 20% of the problem.
Legacy. The Yii2 PHP system must not be aggressively modernized. An AI optimized for greenfield work is actively dangerous here.
Existing AI conventions. Developers have accumulated ad-hoc rules, personal scripts, and prototype agent specs that contain real institutional knowledge โ but no single canonical source. The first job of this architecture is to unify them inside bewith-dev/bewith-docs.
1.5 What We Are Not Trying to Solveโ
We are not trying to make the LLM smarter. We are not trying to replace human judgment. We are not trying to automate code review out of existence. We are not trying to remove developers from the loop.
We are trying to give the LLM the same scaffolding any new hire receives โ written rules, named roles, defined workflows, mandatory quality gates, persistent memory, and a clear escalation path โ so that its output becomes predictable, auditable, and safe to trust within bounded autonomy.
For the operational form of "we are not trying to replace human judgment" on the review surface โ why a review comment is worth more in an AI workflow, and how a human disagreement is kept from being silently coded away โ see Human Review in an AI Workflow.
2. The Solution at a Glanceโ
The solution operates on a simple insight: the rules that the AI follows must live outside the AI's prompt and be enforced by tools that the AI cannot override.
A rule written in CLAUDE.md is a suggestion at temperature greater than zero. A rule enforced by a git hook is binary. We migrate every load-bearing rule into tooling โ git hooks, CI workflows, the Policy Engine, and shared configuration files โ and use the AI's prompt only for guidance the AI is genuinely the right system to enforce.
The system has one repository that holds three concerns:
Governance โ the rules, agents, skills, commands, hooks, policies, and templates. "How we work."
Knowledge โ architecture documents, ADRs, runbooks, glossary, PRDs. "What we know."
Templates โ repository scaffolds, file scaffolds, the new-repo onboarding flow.
All three live in bewith-dev/bewith-docs under separate top-level directories, with a .claude-plugin/plugin.json that publishes the repo as a Claude Code plugin (bewith). The plugin carries no explicit version, so Claude Code resolves it to the git commit SHA and tracks the latest commit (always-latest; see consumption-model.md). Consumer repositories additionally pin the platform's CI logic through each repo's wrapper workflows (uses: bewith-dev/bewith-docs/.github/workflows/<name>.yml@<ref>). There is no separate per-repo lock file.
What runs at session time: the AI loads the local consumer CLAUDE.md, then lazily loads only the agents, skills, knowledge documents, and policies the current task requires. Total context overhead per session is roughly 50KB even though the platform body is roughly 400KB. State persists in GitHub Issue bodies with a ClickUp mirror; local cache is reconciled on session start.
Around all of this, a federation model pins each consumer repository to a specific version of governance, so that upgrades are explicit and rollback is one line.
3. Two Layers: Methodology and Architectureโ
We use two distinct names for two distinct things. Mixing them up has been a source of confusion in earlier discussions.
3.1 Deterministic AI Engineering โ the Methodologyโ
This is the philosophy: the set of beliefs about how AI should be used in production software work.
The core claims of Deterministic AI Engineering:
- AI is a teammate, not a tool.
- Rules belong in tooling, not in prompts.
- The AI should default to autonomous action; humans configure the gates.
- Knowledge of "how we work" and "what we know" must be separated.
- Every load-bearing decision needs a Single Source of Truth that survives developer turnover and model upgrades.
- Quality is enforced by gates that cannot be bypassed, not by reminders that the model may or may not follow.
The methodology is portable across organizations. The architecture below is bewith-dev's specific implementation of it.
3.2 AI Governance Stack โ the Architectureโ
This is the implementation: the concrete repository, files, hooks, agents, skills, workflows, and integrations that realize the methodology at bewith-dev.
The stack is opinionated and specific. It assumes Claude Code as the primary assistant, ClickUp as the task system of record, GitHub for source control and Issues, Confluence for human-facing long-form documentation, Datadog for observability, AWS for infrastructure. Different organizations would build a different stack from the same methodology.
When this document discusses how to think, it uses the methodology name. When it discusses what files to put where, it uses the stack name.
4. Core Principlesโ
These eight principles drive every design decision in the rest of the document. When in doubt, the principles win.
4.1 Determinism via Tooling, Not Promptingโ
A rule that lives only in a markdown file is a suggestion. A rule enforced by a git hook, a CI workflow, a commit lint config, or a Policy Engine YAML is binary. We move every load-bearing rule into tooling.
This includes: branch naming, commit format, ClickUp ID requirements, never-push-to-master, no force-push, test passage, lint passage, contract drift detection, cross-impact analysis. Each is enforced by code, not by prompt.
The AI is told these gates exist and is asked to cooperate. It is not asked to enforce them.
4.2 Single Source of Truth with Lazy Loadingโ
Every rule, agent, skill, command, and policy lives in exactly one file in the governance repository. Consumer overlays may add to the platform but may not redefine it. The build-time validator fails on any redefinition.
At session start, the AI loads only what the current task needs. A frontend bug fix loads the frontend agent, the code reviewer agent, the process guardian agent, and one or two relevant skills. Total context overhead is roughly fifty kilobytes. The platform body is roughly four hundred kilobytes; eighty-five percent of it stays unloaded.
This is what makes detailed expert agents (15โ25KB each) sustainable. The cost is paid only for what's loaded.
4.3 Autonomous by Default, Configurable Gatesโ
Default behavior is autonomous action โ the AI proceeds without asking unless a specific gate stops it.
There are three categories of action:
-
Always autonomous. Branch creation, commits to feature branches, push to non-shared branches, test execution, lint fixes, ClickUp status changes that move a task from "Open" to "In Progress." These never produce a confirmation prompt.
-
Configurable gates. Default off (autonomous), but each developer can opt in to require approval for specific action classes. Examples: posting comments to ClickUp, creating PRs across repositories, applying database migrations.
-
Hard floor. Always requires explicit approval, even if a developer wanted to disable it. Examples: production deploys, force-push to shared branches, secret rotation, destructive database operations (drop, truncate), public communications (Confluence publish, customer-facing email).
The hard floor is the only place where the AI is required to wait. Everything else is the developer's call.
4.4 Manual Workflows Are First-Classโ
A developer who chooses not to use AI for a given task gets the same safety floor as a developer who does. The hooks, CI gates, commit lint, branch name validation โ all of it runs regardless of whether the keystrokes came from Claude Code, another AI assistant, or a human typing directly.
AI is an accelerator. The safety floor is an organizational standard. The two are decoupled.
This matters for the Aviad-and-team conversation: nobody is forced to use Claude. The platform makes AI-assisted work safer and the same platform makes manual work safer. Adoption is incentivized, never compelled.
4.5 State Is Cloud-First, Local-Cachedโ
The authoritative state for an in-progress task lives in the GitHub Issue body's "AI Context" section. The local cache file (.claude/session/active-context.json) is a per-machine convenience for fast resume. On session start, the AI compares the Issue body's updated_at to the local cache; if the Issue is newer, the AI pulls remote and reconciles.
This makes "close laptop, resume on mobile" and "developer is sick, coworker takes over" both trivial. It also eliminates the entire class of bugs that arise from treating local files as source of truth.
4.6 Knowledge โ Governance (but they live in the same repo)โ
"How we work" and "what we know" are separate concerns, but the operational cost of two repositories with two release cycles is higher than the benefit. We keep them logically separated under top-level directories โ governance/, knowledge/, templates/ โ but use one repository, one semver, one CODEOWNERS.
Governance (top-level governance/, policies/, agents/, .claude/, autonomy/, events/, contracts/, configs/) contains agents, skills, commands, policies, hooks, templates. Updated when the process changes.
Knowledge (top-level knowledge/) contains architecture docs, ADRs, runbooks, glossary, PRDs. Updated when the facts change. Knowledge changes do not require a governance version bump; they are released on their own minor-version cadence within the same repo.
The AI may consume both. They review separately (CODEOWNERS routes governance PRs to engineering platform, knowledge PRs to architecture). A single release of bewith plugin vx.y.z declares the snapshot of both that consumers see.
4.7 Federation from Day Oneโ
Even though the pilot starts with three repositories, the federated model is the only model. Every repository points at a pinned version of bewith-docs. Upgrades are explicit. Drift is detectable. Rollback is one line.
This costs one build script and one lockfile per repo. The benefit is that scaling from three repositories to forty-four requires no architectural change.
4.8 The Policy Engine Decides; the AI Followsโ
The Policy Engine is the layer that decides what gates apply to a given task, what risk score the task carries, what agents must be loaded, and what auto-workflows must run. Policies are declarative YAML files in the governance repository.
The AI does not decide. The Policy Engine decides, the AI executes, and the gates verify.
This is the principle that turns "Auto-Applied Workflows" from a vague intention into a testable, auditable mechanism.
5. The Single-Repository Architectureโ
The architecture lives in one repository (the platform) plus a thin template repository for spinning up new consumers. The repository layout is flat โ top-level directories are not grouped under governance//knowledge//templates/ wrappers; the logical separation lives in CODEOWNERS and review routing.
bewith-dev/bewith-docs (the platform; ships as plugin "bewith")
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ VERSION (semver) โ
โ CODEOWNERS (routes governance vs knowledge) โ
โ โ
โ .claude-plugin/ โ
โ plugin.json โ name, version โ
โ marketplace.json โ
โ hooks/hooks.json โ Claude Code hooks decl โ
โ โ
โ .claude/ โ
โ settings.json โ
โ agents/ โ 15 expert agents (planned) โ
โ skills/ โ ~25 reusable capabilities โ
โ commands/ โ ~24 slash commands โ
โ hooks/ โ Claude Code hook scripts โ
โ โ
โ git-hooks/ โ git pre-commit/msg/push + โ
โ sub-hooks + config.env โ
โ โ
โ policies/ โ Policy Engine YAML + schema โ
โ autonomy/ โ defaults.yaml + schema.json โ
โ events/ โ event vocabulary โ
โ configs/ โ shared lint/test configs โ
โ templates/consumer-repo/ โ CLAUDE.md + โ
โ copilot-instructions.md โ
โ โ
โ docs/ โ
โ methodology/ โ this section โ
โ architecture/ + adrs/ + rfcs/ + โฆ โ
โ โ
โ .github/workflows/ โ reusable CI โ
โ scripts/ โ installs + validators โ
โโโโโโโโโโโโโโโโโโโโโโฌโโโโโโโโโโโโโโโโโโโโโโโโโ
โ published as plugin "bewith"
โ (version: "0.1.0" โ POC)
โ
~/.claude/plugins/cache/bewith/
โ installed by `install-developer`
(sandbox CLI: GITHUB_TOKEN + /plugin install
+ git config --global core.hooksPath โฆ)
โ
โโโโโโโโโโโโโโโโโโโโโโผโโโโโโโโโโโโโโโโโโโโโ
โ โ โ
โโโโโโโโผโโโโโโโ โโโโโโโโผโโโโโโโ โโโโโโโโผโโโโโโโ
โ backend- โ โ management- โ โ sqs- โ
โ services โ โ webapp โ โ consumer โ
โ (consumer) โ โ (consumer) โ โ (consumer) โ
โ โ โ โ โ โ
โ CLAUDE.md โ โ CLAUDE.md โ โ CLAUDE.md โ
โ .github/ โ โ .github/ โ โ .github/ โ
โ copilot- โ โ copilot- โ โ copilot- โ
โ instr.md โ โ instr.md โ โ instr.md โ
โ workflows/ โ โ workflows/ โ โ workflows/ โ
โ wrapper โ โ wrapper โ โ wrapper โ
โ uses: @refโ โ uses: @refโ โ uses: @refโ
โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโ
Per consumer repo: a thin scaffold (CLAUDE.md +
copilot-instructions.md) + a wrapper workflow that
calls reusable CI from the platform repo. NO local
platform copy, NO governance.lock.json.
State: GitHub Issue body (authoritative)
ClickUp custom field (mirror โ planned)
Local cache (per-machine โ planned)
Coordination: ClickUp assignee = task owner
(lease mechanism deferred โ see ยง15 note)
Mutations: configurable autonomy with hard floor
Hard gates: Claude Code hooks (plugin-global) +
git hooks (core.hooksPath global) +
CI reusable workflows on every PR
Manual devs / Copilot / mobile: CI is the floor
5.1 Why One Repository, Not Threeโ
The v0.3 draft separated bewith-docs and engineering-knowledge into two repositories. After review, we collapsed them to one. The reasons:
- One semver, one CODEOWNERS, one release pipeline. Two repos meant two release cycles, two version pins per consumer, and constant question of "which one am I editing." One repo collapses that ceremony.
- Cross-references are cleaner. An agent that references an ADR can use a relative path within the same repo. Two-repo cross-refs require a build-time resolver.
- Reviews still separate by CODEOWNERS. Governance changes route to platform reviewers, knowledge changes to architecture, even though they share a repo.
- At our scale (one team, ~10 engineers, 44 repos), two repos was operational theater. The methodology survives just fine with a logical separation inside one repo.
If, at some future point, knowledge grows large enough that it materially slows the bewith-docs release cycle (the team is shipping governance updates daily, knowledge updates monthly, and the merges step on each other), we split. Until then, one.
6. Repository Structureโ
6.1 bewith-dev/bewith-docs (the platform โ plugin name bewith)โ
The layout is flat โ .claude-plugin/, .claude/, git-hooks/, policies/, autonomy/, events/, configs/, templates/, docs/, scripts/, and .github/ all sit directly under the repo root. The governance / knowledge separation lives in CODEOWNERS routing, not in directory paths.
bewith-docs/ # repo name (plugin name is "bewith")
โโโ VERSION # semver, e.g. 0.1.0
โโโ README.md
โโโ CODEOWNERS # routes governance vs knowledge
โ
โโโ .claude-plugin/ # โ what makes this repo a Claude Code plugin
โ โโโ plugin.json # name, version, description
โ โโโ marketplace.json # marketplace catalog (one plugin)
โ โโโ hooks/hooks.json # declares Claude Code hooks (PreToolUse + SessionStart)
โ
โโโ .claude/ # โ agent / skill / command content (lazy-loaded)
โ โโโ settings.json # project-level for working IN bewith-docs
โ โโโ agents/ # expert agents only (lazy-loaded)
โ โ โโโ process-guardian.md # one .md per agent โ no README/template/index
โ โ โโโ ... # (those live in docs/ โ see authoring-agents.md)
โ โโโ skills/ # reusable capabilities โ one dir per skill
โ โโโ commands/ # slash commands โ one .md per command
โ โโโ hooks/ # Claude Code hook scripts (PreToolUse + SessionStart)
โ โโโ block-edit-on-master.sh
โ โโโ block-dangerous-git.sh
โ โโโ block-dangerous-bash.sh
โ โโโ mcp-availability-check.sh
โ โโโ active-context-validate.sh
โ โโโ dangerous-patterns.json
โ
โโโ git-hooks/ # โ git's enforcement layer (separate from Claude's)
โ โโโ pre-commit # orchestrator
โ โโโ commit-msg # orchestrator
โ โโโ pre-push # orchestrator
โ โโโ no-master-edit.sh
โ โโโ branch-name-check.sh # dual-mode by REQUIRE_CU_ID โ ยง6.7
โ โโโ file-size-check.sh
โ โโโ commit-cu-check.sh # opt-in via REQUIRE_CU_ID
โ โโโ typecheck-pass.sh
โ โโโ tests-pass-check.sh
โ โโโ lint-pass.sh
โ โโโ config.env # REQUIRE_CU_ID, REQUIRE_TESTS, โฆ
โ
โโโ policies/ # Policy Engine
โ โโโ schema.json # JSON Schema draft-07
โ โโโ index.md
โ โโโ api-contract-change.yaml, schema-migration.yaml, auth-touch.yaml,
โ legacy-php-change.yaml, frontend-i18n.yaml, production-deploy.yaml,
โ secret-rotation.yaml, large-refactor.yaml, cross-repo-impact.yaml
โ
โโโ autonomy/
โ โโโ defaults.yaml # 7 Hard Floor + 6 configurable + 8 never-ask
โ โโโ schema.json # validates user-overrides.yaml
โ โโโ examples/user-override.example.yaml
โ
โโโ events/vocabulary.md
โ
โโโ configs/ # shared lint/test/build configs
โ โโโ github-workflows/README.md # pointer โ actual workflows in .github/
โ โโโ eslint/, prettier/, tsconfig/, vitest/, commitlint/ (planned)
โ
โโโ templates/consumer-repo/ # scaffold for new consumer repos
โ โโโ CLAUDE.md # placeholder with sections to fill
โ โโโ copilot-instructions.md # entry point pointer for Copilot
โ โโโ README.md # what the scaffold is and is not
โ
โโโ docs/ # โ Docusaurus content (Knowledge)
โ โโโ methodology/ # this section
โ โโโ architecture/, adrs/, rfcs/, decisions/, runbooks/, specs/, onboarding/, templates/
โ
โโโ .github/workflows/ # reusable CI workflows (called from consumer wrappers)
โ โโโ branch-name-check.yml # reusable โ CI mirror of git-hook
โ โโโ file-size-check.yml # reusable โ CI mirror of git-hook
โ โโโ clickup-commit-check.yml # reusable โ PR-title CU-id hard gate
โ โโโ governance-serialize.yml # platform-only โ 13 sensitive paths
โ โโโ deploy.yml # Docusaurus GitHub Pages
โ โโโ validate-pr.yml # frontmatter + policy validators
โ
โโโ scripts/
โโโ checks/check-cu-id.sh # shared validator (git hook + CI)
โโโ install-git-hooks.sh # per-repo escape hatch (core.hooksPath is preferred)
โโโ install-to-consumer.sh # idempotent file scaffolder, no commits
โโโ validate-frontmatter.mjs
โโโ validate-policies.mjs # Ajv + js-yaml
The per-developer machine bootstrap lives in the sandbox CLI (@bewith-dev/cli), not in this repo: bewith platform install verifies GITHUB_TOKEN/GH_TOKEN and registers the bewith plugin in ~/.claude/settings.json. Git enforcement is no longer a manual core.hooksPath step โ the plugin's git-hooks-sync SessionStart hook wires it automatically and keeps it fresh across always-latest updates (see consumption-model.md).
6.2 Consumer Repositories โ what they hold (and do not)โ
Each of bewith-dev's 44 active repositories receives a thin scaffold:
<consumer-repo>/
โโโ CLAUDE.md # 10โ15KB repo-specific (see 6.3)
โโโ .github/
โ โโโ copilot-instructions.md # entry pointer for Copilot
โ โโโ workflows/wrapper.yml # uses: bewith-dev/bewith-docs/.github/workflows/X.yml@vN.N.N
โโโ (optional) git-hooks/config.env # per-repo REQUIRE_* overrides (defaults inherited from the platform)
โโโ (optional) .claude/ # repo-specific agents/skills/commands that shadow the platform
What is deliberately absent under the plugin model: no lock file, no per-repo .claude/effective/, no per-repo agent/skill/command copies, no platform-build step. The platform's content reaches Claude Code via the bewith plugin installed on the developer's machine; the platform's git enforcement reaches every repo via core.hooksPath; the platform's CI logic reaches every PR via reusable workflows pinned by @ref.
6.3 Consumer CLAUDE.md Contentโ
The local CLAUDE.md is the thin slice of project-specific content that cannot live in the platform. It contains:
- Project Overview. What this repo does. Who depends on it.
- Tech Stack. Versions, libraries, internal services consumed.
- Architecture Rules. Boundaries and layering specific to this repo.
- Repo-Specific Conventions. Extensions and exceptions to the platform.
- Forbidden Actions. Repo-specific NEVERs.
- Testing Requirements. Coverage targets, special test patterns.
- Deployment Rules. CI/CD pipeline specifics, environments.
- Domain Concepts. Business glossary used in this codebase.
The three foundational hard rules from ยง16.4 are also embedded at the top of every consumer CLAUDE.md, identically, so they survive any platform refresh and are visible inline.
Template: templates/consumer-repo/CLAUDE.md. Onboarder runs install-to-consumer.sh (idempotent โ see consumption-model.md) to drop CLAUDE.md + .github/copilot-instructions.md into the repo; they then edit CLAUDE.md and commit.
6.4 Why the lock file was droppedโ
The original plan prescribed a governance.lock per consumer repo, citing four benefits: knowing the exact version, one-line upgrade PRs, CI yank detection, and revert-as-rollback. 2026-05-27 decision: dropped.
Each of those benefits is now delivered by simpler artifacts:
- Exact version known per consumer: each
uses: bewith-dev/bewith-docs/.github/workflows/X.yml@vN.N.Nin the consumer's wrapper workflow names the version explicitly. There can be one or many wrappers; they all pin to the same ref by convention. - One-line upgrade: bump the
@refin the wrapper. Same shape as bumping a lock entry. - Yank handling: withdraw or move the marketplace catalog entry. Plugin consumers receive the change via the standard plugin update flow.
- Rollback: git revert the bump.
The cost of the lock file was a separate file per repo, a separate validator workflow (governance-version-check.yml), a separate validator script (scripts/checks/check-governance-lock.sh), and the parallel .yanked.json manifest. All deleted as of 2026-05-27. If audit needs ever require per-repo version recording beyond the wrapper @ref, the lock comes back.
6.5 The Effective Directory (removed)โ
The original plan described a .claude/effective/ directory generated per-consumer at session start by governance-build.sh. It no longer exists. Under the plugin model, the platform's agents/skills/commands live once in ~/.claude/plugins/cache/bewith/.claude/ on each developer's machine; consumer repos never materialise their own copy. See consumption-model.md for the full federation flow.
The original build step (clone pinned platform โ copy into .claude/effective/ โ layer overlay โ validate no redefinitions) has no place in the plugin model. Three reasons:
- Claude Code reads
~/.claude/plugins/cache/<plugin>/natively โ there is nothing forgovernance-build.shto build. - Overlay = Claude Code's native project-over-user scope priority. No custom merge script.
- The build's
governance.lock-based version resolution was tied to the lock contract (ยง6.4), which is gone.
6.7 Branch Naming โ The Single, Final Formatโ
We had two conflicting branch formats in the existing AI_GOVERNANCE/. We pick one, document the rationale, and enforce it via a branch-name-check.sh pre-push hook.
Final format: {type}/{slug}[_CU-{id}] โ underscore-prefix _CU-, suffix optional under lenient mode (see below).
Example with CU-id: feature/commission-per-seat_CU-86c79w47n
Example without: feature/csv-export (allowed when REQUIRE_CU_ID=false)
Why underscore and not parens {type}/{slug}-(CU-{id}):
- Shell-friendly. Parentheses require escaping in
git checkout,gh pr create, shell scripts. Underscores do not. - URL-safe. Parentheses are percent-encoded in URLs; underscores survive untouched.
- GitHub Actions YAML. Branch names with parentheses require quoting in
if: github.head_ref == '...'conditions; underscores do not. - ClickUp linking is identical โ ClickUp matches the
CU-<id>substring regardless of the surrounding characters. - Already in
CONVENTIONS.mdas the "iron" form. We promote the iron form to the standard; the personal-workflow rule that used parens is rewritten.
The hook is dual-mode, driven by REQUIRE_CU_ID in git-hooks/config.env:
REQUIRE_CU_ID=trueโ branch must include_CU-{valid-id}. The id is validated by the sharedscripts/checks/check-cu-id.shโ โฅ6 alphanumeric chars with at least one digit AND one letter. Placeholders likeCU-pending,CU-tbd,CU-xxx,CU-000000fail by design โ there is no denylist; the digit-plus-letter rule rejects them naturally.REQUIRE_CU_ID=falseโ the_CU-{id}suffix is optional. If present, the id is still validated the same way (no placeholder workarounds). If absent, the branch passes.
The structural regexes:
# Strict (REQUIRE_CU_ID=true)
^(feature|bug|hotfix|infra|chore|refactor|docs|proposal)/[a-z0-9][a-z0-9-]*_CU-([a-zA-Z0-9]+)$
# Lenient (REQUIRE_CU_ID=false)
^(feature|bug|hotfix|infra|chore|refactor|docs|proposal)/[a-z0-9][a-z0-9-]*(_CU-([a-zA-Z0-9]+))?$
The docs and proposal types were added to the original list (feature|bug|hotfix|infra|chore|refactor): docs keeps documentation-only branches distinguishable from chore, and proposal carries team-rule / proposal branches (e.g. proposal/team-rule-<slug> โ a single slash, the type plus a hyphenated slug). This matches the enforcers in git-hooks/branch-name-check.sh and .github/workflows/branch-name-check.yml. Id charset is [a-zA-Z0-9] (ClickUp ids can include uppercase under some namespaces).
Multi-actor prefixes (cc-ariel/..., cp-cloud/...) from the original plan are not currently enforced; the lease mechanism that motivated them is deferred (see ยง15 note).
7. The End-to-End Flowโ
This section describes how a single piece of work moves from idea to production under the Governance Stack. The flow is the spine of the system; everything else exists to support it.
7.1 Three Domains, in Orderโ
The full SDLC covers three concentric domains. We implement them in order.
Domain 1: Engineering. Ticket โ claim โ context load โ policy evaluation โ agent routing โ design plan โ implementation โ tests โ PR โ review โ QA โ release โ monitoring โ close.
Domain 2: Product. Idea โ research โ customer pain โ PRD โ UX โ success metrics โ ticket generation. The product flow culminates in a ClickUp parent task with linked GitHub Issues for implementation slices.
Domain 3: Company. Support โ sales โ analytics โ customer success โ management.
The Engineering Domain is what we build first because it is where AI is most useful and where the failure modes hurt most. The Product Domain comes next; the Company Domain is deferred to a later phase.
7.2 The Engineering Flow in Detailโ
A ticket exists in ClickUp. A developer (or the AI on their behalf) runs /continue. The thirteen-step autonomous loop begins (ยง8). After the loop completes (PR merged), the work moves into deployment monitoring and finally closes.
The flow is not linear in the strict sense โ gates can send the AI back to earlier steps. A failed contract diff sends the AI back to the design step. A failed test sends it back to implementation. A code review rejection sends it back to implementation with notes.
The flow is fully recoverable from any interruption because state lives in the GitHub Issue body, not in the AI's memory.
7.3 Where Each System Holds Authorityโ
| System | Authoritative for | Mirror in |
|---|---|---|
| ClickUp | Product tasks, priorities, statuses, business context, customer-facing task chatter | GitHub Issues (linked) |
| GitHub Issues | Per-PR implementation tracking, AI Context block, design tracking issues | ClickUp custom field ai_context (condensed) |
| GitHub PR | Code review, merge gate, deploy trigger | (none) |
bewith-docs repo | Governance + Knowledge | (none โ this is the canonical) |
| Confluence | Long-form human reading, customer-facing pages, meeting notes | Pointer to relevant bewith-docs/docs/ doc |
This split means a product manager sees ClickUp; an engineer sees GitHub Issues + PRs; an architect reads knowledge/ in the repo and links to Confluence for long-form context. No one system holds two authorities.
8. The Thirteen-Step Autonomous Loop (/continue)โ
This is the operational heart of the system. When a developer types /continue (or "continue working" / "ืืืฉื ืืขืืื"), the AI executes the following thirteen steps autonomously until a hard gate or completion stops it.
The steps are not arbitrary. Each one corresponds to a known failure mode that ad-hoc AI usage produces.
Step 1: Load Governance (Lazy)โ
The AI reads the local CLAUDE.md (~10โ15KB). It does not load every agent or skill. It loads only the router and the global rules. Total context: ~10KB.
This step prevents the "loading 400KB of context for a one-line change" failure.
Step 2: Identify the Active Taskโ
The AI checks for an in-progress GitHub Issue assigned to the current actor. If found, it reads the Issue body's "AI Context" section. If not found, the AI fetches open ClickUp tasks for the current user and presents them.
If multiple ClickUp tasks are assigned to the user, the AI does not auto-pick. It presents the list and lets the user choose. This prevents the "AI picked the wrong ticket and started writing code" failure.
If multiple users are assigned to the same ClickUp task, the AI stops and asks who is actually doing the work. This prevents the claim race.
Step 3: Reconcile Stateโ
The AI compares the GitHub Issue body's updated_at with the local cache. If the Issue is newer (someone updated it from another machine), the AI pulls remote, reconciles, and updates the cache. The Issue body wins ties.
This step makes mobile resume and coworker handoff transparent. The full reconciliation algorithm is ยง14.3.1.
Step 4: Evaluate Policiesโ
The AI examines the task and the files it expects to touch. The Policy Engine runs against this view of the world. Each matching policy contributes:
- Required agents to load
- Required gates that must pass
- Risk score
- Auto-workflows to run later
- Whether explicit human approval is required
If a policy returns "human approval required" and the configurable autonomy is set to gated for that class, the AI stops and requests approval. Otherwise, it proceeds.
Step 5: Load Relevant Expert Agentsโ
Based on the policy output, the AI loads the agents it needs. A backend API change loads backend-developer.md, database.md, auth-security.md, code-reviewer.md, process-guardian.md. A frontend i18n change loads frontend-developer.md, i18n-localization.md, accessibility.md (via skill), code-reviewer.md.
Loading happens at this step, not at session start, because step 4 just told us what we need. Total agent context: typically 50โ70KB.
Step 6: Build or Update the Planโ
The AI reads any existing plan in the Issue body. If absent, it drafts one. The plan is a numbered list of concrete steps: which files to touch, which tests to add, which contracts to update, which migrations to write.
The AI presents the plan and waits for either approval or correction. This is the one place the AI always pauses for human input โ not because it's a configurable gate, but because catching a wrong plan here is dramatically cheaper than fixing wrong code later.
Once the user approves (or corrects and approves), the plan is written to the Issue body and the AI proceeds.
Step 7: Create or Update the Branch (with Lease)โ
The AI acquires a working-state lease (ยง15.6), then checks the current branch. If the branch matches the task's expected name ({actor}/{type}/{slug}_CU-{id}), it continues. If not, it creates the branch.
The branch name format is enforced by a pre-push hook regardless of who creates the branch.
Step 8: Implement in Chunksโ
The AI implements the plan one chunk at a time. After each chunk:
- Tests for that chunk are written (per the testing strategy in ยง17)
- The chunk's commit is staged and committed with a CU-id reference
- The AI updates the Issue body's "AI Context" section if at a meaningful checkpoint
The state-sync skill runs in the background, persisting context every 30 minutes or every 3 commits.
Step 9: Run Local Verificationโ
The AI runs the repo's verify.sh script. This typically includes type checking, linting, the full unit test suite, integration tests with Testcontainers, and contract validation. If anything fails, the AI either fixes (when the fix is small and clearly within scope) or escalates to the user (when the fix is non-trivial or out of scope).
Step 10: Open the Pull Requestโ
The AI pushes the branch and opens a PR. The PR title ends with the CU-id token (bare CU-<id> is the convention, uniform with the branch suffix _CU-<id>, e.g. fix(scope): summary CU-86c9v71z4; [CU-<id>] is also accepted). The "closes #N" reference to the GitHub Issue and the ClickUp task link live in the PR body, which also summarizes what changed, lists test results, and references any ADRs created.
A CI workflow ai-pr-review.yml runs the code-reviewer agent against the diff and posts its findings as a PR comment.
Step 11: Handle Code Reviewโ
If the PR receives review comments, the AI reads them, addresses what it can, and asks the user about ambiguous requests. It does not auto-merge.
A configurable gate may be set here: some teams want explicit human approval before pushing review-response commits; others want full autonomy.
Step 12: Wait for Mergeโ
The AI waits for the human(s) to merge (or merges itself if so configured). Once merged, the GitHub Issue closes automatically via the "closes #N" reference. The state-sync skill flushes a final "AI Context" update summarizing what shipped.
Step 13: Monitor and Closeโ
After merge, the watch-deploy skill watches the deployment pipeline. If deployment succeeds and Datadog shows no anomalies for a defined window, the loop closes. If deployment fails or telemetry anomalies appear, the incident-response workflow kicks in.
ClickUp status updates to "Done" (configurable gate, but default autonomous for moving to Done after successful deploy).
The loop is now complete. The AI is ready for the next /continue.
9. The Policy Engineโ
The Policy Engine is the layer that decides what gates apply to a given task. It is declarative, testable, and auditable.
9.1 Why a Policy Engineโ
Without an explicit Policy Engine, "what gates apply when" lives implicitly in the AI's behavior. Different sessions interpret the same situation differently. A schema change in one session triggers a migration check; in another session, it doesn't. The result is non-determinism, even with detailed agent files.
With an explicit Policy Engine, the gates are visible. A developer can read the YAML and predict the AI's behavior. A CI workflow can run policies in dry-run mode against a PR diff and show what would happen. A failed gate produces a comprehensible error: "Policy api-contract-change.yaml requires contract diff check; it failed because X."
The Policy Engine also absorbs the Risk Engine concern. Each policy outputs a risk score; the score determines whether human approval is required, regardless of the configurable autonomy setting.
9.2 Anatomy of a Policyโ
A policy is a YAML file in governance/policies/. It has the following structure:
id: api-contract-change
name: API Contract Change
description: |
Triggered when any file changes that defines an external API contract
(PHP controllers, OpenAPI spec, Zod schemas in contracts package).
Ensures contract diffs are checked, breaking changes get human approval,
and downstream consumers are scanned.
triggered_by:
- file_change: "api/**/*.php"
- file_change: "openapi.yaml"
- file_change: "contracts/zod/**"
risk:
score: 8 # 1-10
blast_radius: high
reason: "Contract changes propagate to all consumers (FE, mobile, integrations)"
required_agents:
- languages/php
- layers/backend
- lifecycle/api-contracts
required_gates:
- id: contract_diff
description: "Run contract diff tool, compare before/after schemas"
- id: consumer_scan
description: "Search frontend/mobile repos for usages of changed endpoints"
- id: breaking_check
description: "Identify removed or renamed fields"
auto_workflows:
- on: non_breaking_change
action: "regenerate-ts-types-in-frontend"
- on: breaking_change_detected
action: "open-issue-in-frontend-repo-with-impact-details"
human_approval_required:
- condition: "breaking_change_detected"
- condition: "risk.score >= 7"
9.3 How Policies Runโ
When the AI enters Step 4 of the autonomous loop, the Policy Engine examines the proposed work:
- Identify all files the AI expects to touch (from the plan or from the actual diff if implementation has started).
- For each policy in
policies/, check whether anytriggered_byclause matches. - For each matching policy:
- Aggregate required agents into the load list.
- Aggregate required gates into the gate list.
- Compute the maximum risk score.
- Aggregate auto-workflows by phase.
- Determine whether human approval is required.
- Return the aggregated decision.
The AI executes the decision: loads the agents, runs the gates, defers the auto-workflows to their phase, requests approval if necessary.
9.4 The Event Vocabularyโ
Policies are triggered by events. The events live in governance/events/vocabulary.md. Examples:
file.changedschema.modifiedendpoint.addedendpoint.signature_changedmigration.createdsecret.referencedauth.touchedi18n.string_addeddeploy.requested
The vocabulary is a markdown document, not an event bus. The mapping from events to policies is the YAML in each policy file. We deliberately avoid building or adopting a real event bus at this scale; the team is one team and the events come from a small number of well-known sources (git, CI, ClickUp). When the scale demands it (50+ services, 100+ engineers), a real event bus may be appropriate. Until then, the vocabulary document plus YAML policies handle the same need at one percent of the complexity.
10. Configurable Autonomyโ
Default: autonomous.
10.1 The Three Categoriesโ
Always autonomous. The AI never asks. These are actions that are reversible, low-risk, and constant. Branch creation, commits to feature branches, push to feature branches, test execution, lint fixes, type checking, ClickUp status changes that move a task from "Open" or "Backlog" to "In Progress."
Configurable gates. Default autonomous. Each developer can opt in to require approval for specific action classes. Examples: posting comments to ClickUp, creating PRs across repositories, applying database migrations, ClickUp status changes to "Done."
Hard floor. Always requires explicit approval, regardless of any developer's configuration. Examples: production deploys, force-push to shared branches, secret rotation, destructive database operations (drop, truncate), public communications (publishing to Confluence, sending customer-facing email), modifying CODEOWNERS.
10.1.1 Criteria for the Hard Floorโ
An action belongs in the Hard Floor if and only if it meets all four of the following criteria. The criteria exist so that the Hard Floor stays small and meaningful โ adding everything that "feels risky" would turn the autonomous loop back into approval theater.
Criterion 1: Irreversibility. Undoing the action requires significantly more effort than performing it, or is impossible. A production deploy of a broken build requires a rollback procedure. A force-push to a shared branch destroys colleagues' work that may not be recoverable. A secret rotation invalidates running sessions across services. A DROP TABLE cannot be undone without a backup restore.
A reversible action โ even a high-risk one โ does not belong in the Hard Floor. A commit to a feature branch may produce bad code, but it is trivially reversible with another commit. It belongs in "always autonomous."
Criterion 2: Blast radius beyond the current actor. The action affects users, systems, or developers outside the person running Claude. A production deploy affects every customer. A force-push to a shared branch affects every colleague on that branch. A Confluence publish affects everyone who reads the page.
A high-impact action that affects only the current actor โ like reformatting their local files โ does not belong in the Hard Floor.
Criterion 3: No effective recovery via tooling. If the action goes wrong, there is no automated rollback, no CI gate that catches it next, no quick fix in the next commit. If a CI gate already catches the action downstream โ for example, contract breaking changes caught by contract-impact-analysis.yml before merge โ the action is not a Hard Floor item, because the CI gate is the safety net.
Criterion 4: Reasonable developers do not disagree about the default. If reasonable developers all agree the action should be autonomous (creating a branch) or all agree it should require approval (production deploy), the answer is clear. If they disagree, the action belongs in the configurable middle, not the Hard Floor. This criterion keeps the floor short and the friction justified.
10.1.2 The Definitive Hard Floor Listโ
Applying the four criteria, the Hard Floor contains exactly:
- Production deploys โ irreversible (rollback is recovery, not undo), affects all customers, no CI catches a bad deploy after it ships.
- Force-push to shared branches (master, develop, release/*) โ destroys history irreversibly, affects all colleagues, no recovery past local reflog windows.
- Secret rotation โ invalidates running sessions, affects all services using the secret, recovery requires coordinated reissue.
- Destructive database operations in production โ
DROP TABLE,TRUNCATE, unrestrictedDELETE, schema changes that drop columns with data โ irreversible without backup restore, affects all consumers. - Public communications โ Confluence publish to non-draft pages, customer-facing email, posts to public Slack channels โ irreversible (retraction does not unsend), affects external readers.
- CODEOWNERS modification โ changes who can approve PRs across the repo, affects every future PR, recovery requires a counter-PR with the same approval.
- Governance lockfile modification โ changes which platform version this repo follows, affects every future AI session in this repo, recovery requires a counter-PR.
This is the entire list. New additions require an ADR demonstrating that the action meets all four criteria.
10.1.3 How the Hard Floor Is Enforcedโ
The Hard Floor is enforced in three places, not just by prompt. The AI is non-deterministic; a single layer would be one missing prompt away from a production incident.
- The autonomy YAML. The items live in
always_require_approvalinautonomy/defaults.yaml. The Policy Engine checks this on every action. - The git hooks and CI workflows. Several items are physically blocked at the tooling level.
block-edit-on-master.shprevents direct edits to shared branches.block-dangerous-git.shprevents force-push. The deploy script requires a manual confirmation flag that the AI cannot synthesize. - The expert agents. The auth-security, devops-infra, and database agents each reference the relevant Hard Floor items in their "Hard Rules" section. Agents that touch these domains remind the AI explicitly.
10.2 The Platform Defaults Fileโ
The platform ships with governance/autonomy/defaults.yaml:
# Hard floor - cannot be disabled
always_require_approval:
- production_deploy
- force_push_to_shared_branch
- secret_rotation
- destructive_db_operation
- public_communication
- codeowners_modification
# Configurable - default off (autonomous), per-user can enable
configurable_gates:
clickup_comment_post: { default: off }
clickup_status_to_done: { default: off }
cross_repo_pr_creation: { default: off }
schema_migration: { default: off }
api_contract_breaking: { default: off }
large_refactor: { default: off, threshold: 20_files }
# Always silent - never ask, regardless of any config
never_ask:
- branch_creation
- commit_to_feature_branch
- push_to_feature_branch
- test_execution
- lint_autofix
- type_check
- clickup_status_to_in_progress
- state_sync_update
10.3 Per-User Overridesโ
Each developer maintains a personal ~/.claude/user-overrides.yaml:
user: ariel
overrides:
schema_migration: on # I want approval on schema changes
clickup_comment_post: on # I want approval before AI comments
The override file is in the developer's home directory, not in any repo. It is personal. It is not committed.
10.4 Why This Worksโ
A configurable autonomy model lets the organization set the hard floor (the things no one should be allowed to do silently) while letting individual developers tune their own comfort level for the rest. Senior engineers run mostly autonomous. New hires can crank up the gates. Both work inside the same architectural framework.
This is also visible. Every developer can read the platform defaults and their own override and predict the AI's behavior. There is no hidden state.
11. The Full SDLC โ Flows Claude Will Driveโ
Beyond the implementation loop (ยง8), Claude participates in the full software development lifecycle. This section enumerates the flows the team will use day-to-day, mapped to commands and to who triggers them.
11.1 Product Planning Flowsโ
Idea capture (/idea). A developer or PM types /idea <short description>. Claude runs the idea-to-spec workflow: clarifying questions, search for prior art (bewith-docs/docs/ + ClickUp + Confluence), draft of a product brief, optional save to the developer's personal ClickUp backlog (see ยง11.5).
Spec validation (/spec-validate, auto-applied). When a ClickUp task in "Spec" status is opened in a /continue session, Claude loads the product-manager agent and validates clarity, completeness, testability, and business alignment. If any axis fails, Claude proposes a revision and asks the PM to confirm before the task advances to "Ready for Design."
Design review (/design-review). Triggered by the developer or PM. Claude loads architect, fetches the ClickUp task and the linked spec, performs Phase 1 (product decomposition), Phase 2 (technical discovery, repo + Confluence + GitHub search inside bewith-dev only), Phase 3 (full DR document). Output goes to knowledge/adr/ if architecturally significant, or to the GitHub Issue body if scoped to a single PR. Confluence publish is optional and gated.
Parent task breakdown (/breakdown). Given a ClickUp parent task with a DR, Claude proposes a child-task structure: implementation tickets, each PR-sized, each with its own GitHub Issue once started. The PM or tech lead approves the structure before Claude creates the ClickUp subtasks.
11.2 The Parent vs Child Split (Product vs Engineering Tasks)โ
bewith-dev's task model has two layers, and Claude respects both:
- Parent task in ClickUp = the product unit. This is what the PM, sales, support, and management see. Status reflects the feature's overall progress. Acceptance criteria live here.
- Child task in ClickUp + GitHub Issue = the engineering unit. Each child is one PR's worth of work. The GitHub Issue holds the AI Context block, the implementation plan, and the working state. ClickUp child task mirrors high-level status.
When a developer runs /continue and Claude sees a parent with no children, Claude offers to run /breakdown first. When Claude sees children, it picks the next one (or asks if multiple are unblocked).
This split is what makes "the product team sees ClickUp, the engineers see GitHub Issues" work in practice.
11.3 Implementation Flowsโ
Covered fully in ยง8 (the thirteen-step loop). Key commands:
/continueโ resume from state and run the autonomous loop./planโ show the current implementation plan and wait for approval./feature-tasksโ sub-task the current parent into PR-sized issues./local-testโ sandbox docker-compose validation againstsandbox/./verifyโ run the full local verification suite./hotfixโ fast-track flow with documented gate skips.
11.4 Code Review and Merge Flowsโ
PR review (/pr-review). Reviews a colleague's PR. Loads code-reviewer, applies the platform's ten-point checklist against the diff. Posts findings as draft comments awaiting human approval before publishing to GitHub.
Definition of Done (/done). The Process Guardian agent runs the DoD checklist before Claude announces a task complete. Blocks closure if any required item is unchecked.
11.5 Personal Backlog and Improvement Ideasโ
/improvement-idea. A developer has an idea โ process improvement, tool wish, refactor opportunity. Claude:
- Analyzes what exists today (searches
bewith-docs/, the relevant consumer repos, ClickUp, Confluence) to avoid duplication. - Identifies the gap between idea and current state.
- Proposes the minimal next step: "you can already do this โ here's how," or "this is a small change, here's the proposed PR," or "this is bigger โ let's open a personal backlog ticket."
- If the developer approves a backlog item, Claude creates a ClickUp task in the developer's personal "Ideas" list (not a team list) with a structured body: what was asked, what exists, gap, recommendation, follow-up options.
- Later, when the developer says "deep dive on CU-xxx," Claude loads the prior analysis, expands with risk/alternative analysis, and produces a shareable summary suitable for proposing to the team.
This is how developer-discovered improvements become trackable without becoming team-meeting overhead.
11.6 Status and Digest Flowsโ
/status. "What's on my plate?" Claude pulls the developer's open ClickUp tasks, open GitHub Issues, open PRs, and active leases. Groups by urgency:
- Now โ blocked, overdue, or in active session
- Today โ in-progress, high priority
- This week โ assigned, not yet started
- Watching โ assigned to others, but waiting on the developer for review or input
The digest is short. Each line links the ClickUp task and any related GitHub Issue/PR. Optionally renders as a persistent Cowork artifact so the developer can refresh it tomorrow.
/status @colleague. Same digest for a teammate. Useful for a tech lead's morning sweep or for a stand-in covering a sick coworker. The status is factual (what's open, what's blocked) and does not include subjective tone.
/daily-summary. End-of-day summary the developer can post as a stand-up note: what shipped, what's in review, what's stuck, where help is needed. Five lines.
/team-status (manager-flavor). Loads the eng-manager skill. Aggregates the team's open work, surfaces who has too many parallel leases (>3), who is blocked on whom, where cross-repo work is colliding (via cross-impact-check.yml results). Output is a manager-style brief, not a code review.
11.7 Operations Flowsโ
/investigate <symptom>โ Datadog log dig + infra-mcp reads. Output is a structured "what we know" report, not a fix./incidentโ incident coordination workflow. Creates a war-room channel link, pulls Datadog dashboards, drafts a post-mortem skeleton./runbook <name>โ load and execute a runbook fromknowledge/runbooks/.
11.8 Architecture and Decision Flowsโ
/adr <topic>โ create a new ADR. Loadsdecision-recorderagent. Output goes toknowledge/adr/NNN-<slug>.mdand gets linked from the relevantknowledge/architecture/doc./audit <repo>โ full engineering audit of a consumer repo: rule conformance, test coverage, contract drift, security posture, outdated dependencies. Outputs an audit report toknowledge/audits/<repo>-<date>.md.
11.9 Onboarding and Helpโ
/init-claudeโ first-time machine setup verifier (was/bewith-ai-init). Checks MCP connections, ClickUp auth, GitHub auth, governance pin, sandbox status./help-bewithโ capabilities catalog: every slash command, every workflow, every MCP, every doc.
11.10 Release Flowsโ
Covered in detail in ยง18. Summary commands:
/release-cutโ propose a release fromdeveloptomaster, generate release notes from merged PRs since last tag, draft the tag message./shipโ execute the release (verify + bump + tag + push). Hard-floor approval required.
12. The Expert Agentsโ
The Governance Stack ships with fifteen expert agents. Each is a detailed markdown file in governance/agents/, sized 15โ25KB, structured in the same BeWith canonical agent template.
12.1 Why Detailed, Not Condensedโ
A common temptation is to keep agents short. "Backend developer: write good NestJS code, validate inputs, log errors." This fails because the agent has nothing concrete to enforce.
bewith-dev's domain has complex specifics โ Cognito flows, two databases with different patterns, NestJS module structure conventions, RPC topology, i18n with Hebrew RTL, legacy PHP boundaries โ that need depth. We size agents at 15โ25KB and rely on lazy loading to keep session-level context manageable.
The migration starting point: bewith-dev/agents-developer-kit/ already contains 12 agents authored by Aviad in March 2026, sized 500โ1300 lines each. They are the substantive content. The migration is a rewrite to the BeWith canonical agent template, not a from-scratch authoring exercise. We preserve Aviad's domain content while normalizing structure.
12.2 The Canonical Agent Templateโ
The original plan prescribed a 9-section body (Role, Scope, Hard Rules, Common Pitfalls, Reference Patterns, Quality Checklist, Handoff Points, Cross-References, Anti-Patterns). Implementation moved to a lighter 7-section body that aligns with Anthropic's canonical sub-agent pattern (Role โ When invoked โ Checklist โ Output format) plus two BeWith-specific additions (Handoff Points, Cross-References, optional Anti-Patterns). Reason: the body becomes the agent's custom system prompt โ Anthropic's documented shape loads better and is easier to maintain; the BeWith additions preserve multi-agent discipline. See docs/templates/agent-template.md.
Every agent file under .claude/agents/ consists of:
Frontmatter (parsed by Claude Code):
name(required) โ kebab-case, matches filename.description(required) โ what the agent owns + when it loads. Include "use proactively" for auto-routing per Anthropic docs.tools(recommended) โ restrictive allowlist. Reviewer / gatekeeper agents useRead, Grep, Glob, Bash(no Edit/Write); implementer agents inherit all.model: inherit(recommended) โ follow the session's model.
Body (becomes the agent's system prompt โ 7 sections in order):
- Role. One paragraph: what authority + what scope + what NOT in scope.
- When invoked. Numbered workflow steps from load to finish (Anthropic canonical).
- Checklist / Hard rules. Either
- [ ]markdown checklist or numbered MUST/MUST NOT statements. Items resolve to observable artifacts where possible. - Output format. The exact format of what the agent produces โ review comments, blocking messages, ADR drafts. Real markdown/code templates, not abstract pseudo-code (Anthropic canonical).
- Handoff points. When this agent stops and brings another in. BeWith-specific addition.
- Cross-references. Pointers to related agents, policies, methodology docs. BeWith-specific addition.
- Anti-patterns. What this agent must never do, with examples. Optional but recommended for high-stakes agents.
Sections 4 ("Common Pitfalls"), 5 ("Reference Patterns"), and 2 ("Scope") from the original plan are folded into the lighter shape โ Pitfalls merge into Anti-Patterns, Reference Patterns merge into Output format, Scope merges into Role + the description frontmatter.
12.3 The Fifteen Agentsโ
architect.md. Design authority. Microservice boundaries, RPC vs HTTP, event-driven vs request-response, database choice (Mongo vs Aurora). Drafts ADRs. Loaded when scope is unclear or cross-service contracts change. (Source: agents-developer-kit/agents/ARCHITECT.md โ rewrite to template.)
product-manager.md. Product quality gate. Validates specs for clarity, completeness, business alignment, testability. Loaded for any new feature or spec validation. (Source: agents-developer-kit/agents/PRODUCT_AGENT.md.)
team-leader.md. Orchestrator. Approves stage transitions. Coordinates handoffs between humans and AI sessions. Escalates blockers. Loaded for SDLC orchestration decisions. (Source: agents-developer-kit/agents/TEAM_LEADER.md.)
backend-developer.md. NestJS implementation specialist. Module structure, MongoDB patterns, Aurora MySQL, Redis caching, TCP RPC, Cognito integration, infra-mcp usage for local validation, repository pattern, validation pipes. Loaded for backend tasks. (Source: agents-developer-kit/agents/BACKEND_DEVELOPER.md.)
frontend-developer.md. Next.js + React implementation. MUI design system, i18next, Hebrew RTL, accessibility, state management, API client patterns, Cognito client integration. Loaded for frontend tasks.
qa-engineer.md. Testing authority. Unit (Vitest), integration (Vitest + Testcontainers), E2E (Playwright). Coverage targets per repo (ยง17.3). Test data lifecycle. Mock vs real DB decisions. Loaded for any change that alters production behavior. (Source: agents-developer-kit/agents/TESTIM_E2E_SCENARIOS.md updated for new stack; new content from tests_plan.md.)
code-reviewer.md. Pre-PR and PR review. Ten-point checklist: CLAUDE.md compliance, architecture boundaries, test coverage, dep justification, contract drift, secrets, backward compatibility, PR size, auth/security touched, overengineering. Loaded automatically before PR open. (Source: agents-developer-kit/agents/CODE_REVIEWER.md.)
database.md. Schema design, migrations, indexing, query optimization, idempotency, transactions, document size management (Mongo) and join planning (Aurora). Loaded when DB schema changes.
devops-infra.md. ECS, Kubernetes (via Pulumi), Terraform, GitHub Actions, Datadog dashboards, environment variables, Secrets Manager, container registry. Loaded for infra changes. (Source: agents-developer-kit/agents/GITHUB_ACTIONS_CI_CD.md plus new infra content.)
auth-security.md. Cognito flows (passwordless, MFA, SSO), JWT, RBAC, OWASP top 10, input sanitization, rate limiting, secret storage. Loaded for any auth touch. (New agent; some content from existing skills bewith-permissions-demo-tokens.)
analytics-observability.md. Datadog (logs, traces, metrics, dashboards), CloudWatch, structured logging conventions, distributed tracing. Loaded for log investigation or adding instrumentation.
i18n-localization.md. i18next conventions, Hebrew RTL, translation workflow, MUI direction setting. Loaded for user-facing text changes.
legacy-php-guide.md. Yii2 patterns in legacy repos. Boundary discipline: small safe changes only, no architecture refactors, explicit human review for risky changes (auth, payments). Loaded for any change in legacy PHP repos. Note: a policy also enforces this โ the agent is the explanation, the policy is the gate. (Source: agents-developer-kit/agents/LEGACY_CODE_GUIDE.md.)
decision-recorder.md. Generates ADRs from design discussions. Maintains consistent ADR format and indexing in knowledge/adr/. (New agent.)
process-guardian.md. Definition of Done gate. The last reader before the AI closes any task. Verifies the checklist, raises any unchecked items, blocks closure until they are addressed. (New agent; absorbs the existing definition-of-done.md workflow.)
12.4 Routing Matrixโ
The AI does not pick agents from a single list. It picks from a two-dimensional matrix: language ร layer. A change to a backend PHP file loads PHP from languages/ and Backend from layers/. A change to a frontend TS file loads TS and Frontend. A change to a database migration loads SQL/Mongo and Database. The Policy Engine outputs the full set in step 4 of the loop.
In the repository layout, agents are listed flat (agents/backend-developer.md rather than agents/layers/backend-developer.md) for simplicity. The routing matrix is encoded in the agents/ROUTING.md index and in the policy required_agents clauses.
13. Workflows, Commands, and Skillsโ
The system distinguishes three kinds of executable knowledge.
13.1 Workflowsโ
A workflow is a procedural document in governance/docs/workflows/. It describes a multi-step process. Workflows are not directly invoked; they are read by the AI when needed.
The eighteen workflows are grouped by stage of the SDLC.
| # | Stage | Workflow | Triggered by |
|---|---|---|---|
| 1 | Idea capture | idea-to-spec | /idea |
| 2 | Spec validation | spec-validation | auto (when spec is drafted) |
| 3 | Parent task breakdown | parent-task-breakdown | /breakdown |
| 4 | Comprehensive planning | design-review | /design-review |
| 5 | Architecture decision | architecture-decision | /adr |
| 6 | Detailed task creation | task-breakdown | /feature-tasks |
| 7 | Implementation loop | development-loop | within /continue |
| 8 | Local testing | local-testing | /local-test |
| 9 | Postman creation | postman-collection-update | /postman-update |
| 10 | Colleague PR review | pr-review-chat | /pr-review |
| 11 | Definition of Done | definition-of-done | /done |
| 12 | Hotfix flow | hotfix | /hotfix |
| 13 | Real-time debug | log-investigation | /investigate |
| 14 | Incident response | incident-response | /incident |
| 15 | Daily standup | daily-summary | /daily-summary |
| 16 | Session resume | continue-session | /continue |
| 17 | Parallel work view | parallel-work | /parallel-status |
| 18 | Handoff | handoff | /handoff |
PR creation does not have its own workflow file โ it lives inside development-loop.md because it is a final step of the implementation loop, not a separate process.
13.2 Slash Commandsโ
A command is a user-invokable workflow trigger. Each command is a markdown file in governance/.claude/commands/. The full command list:
/continue โ resume from state and run the autonomous loop
/plan โ show the implementation plan and wait for approval
/discover โ discovery process for a new feature or project
/idea โ capture an idea and draft a spec
/improvement-idea โ process improvement; analyze, optionally save to personal backlog, optionally deep-dive
/breakdown โ break an epic into sized child tasks
/design-review โ architect-led design with ADR output
/feature-tasks โ sub-task into PR-sized issues
/local-test โ sandbox docker-compose validation
/postman-update โ create or update Postman collection
/pr-review โ review a colleague's PR
/done โ Definition of Done gate
/hotfix โ fast-track with documented gate skips
/investigate โ log investigation via Datadog + infra-mcp
/incident โ incident coordination and post-mortem
/daily-summary โ five-line standup draft
/status โ my open work, grouped by urgency
/status @colleague โ someone else's open work
/team-status โ team-level status digest for managers
/parallel-status โ view own active leases
/handoff โ push state to Issue and notify next actor
/audit โ full engineering audit of a repo
/adr โ create a new Architecture Decision Record
/runbook โ load an operations runbook
/verify โ full verification suite (typecheck + lint + test + contract)
/release-cut โ draft release notes + propose tag from developโmaster
/ship โ release to production (verify + bump + tag + push, with hard-floor approval)
/init-claude โ first-time machine setup verifier
/help-bewith โ capabilities catalog
13.3 Skillsโ
A skill is a reusable capability triggered automatically by keyword or invoked by the AI from within a workflow. Each skill is a SKILL.md file in its own directory under governance/.claude/skills/. Skills typically wrap a tool, an MCP call, or a procedure.
The core skills:
Domain skills. agent-guard, state-sync, mcp-preflight, sandbox-orchestrator, clickup-task-load, clickup-comment-draft, bewith-datadog-logs, postman-collection-builder, jam-bug-analyzer, webapp-testing (Playwright), bewith-a11y-review, bewith-i18next-translation, bewith-coderabbit-implement, bewith-mermaid-diagrams, bewith-permissions-demo-tokens, bewith-identify-bug.
Meta skills. config-audit, governance-sync, template-sync-audit, sync-from-template, skill-creator, permission-manager, git-guardrails.
Operational skills. oncall, oncall-setup, server-logs, watch-deploy, deploy-manager, staging-ci, incident-manager, session-summary, peak-hours-advisor, lease-heartbeat.
Engineering management skills. eng-manager, triage-issue, request-refactor-plan, tidyup, perf-audit, launch-checklist, infra-advisor, frontend-design, design-an-interface, ai-collab.
The meta skills deserve special attention. config-audit audits the governance files themselves for drift, contradictions, or out-of-date references. governance-sync applies the fixes back to the platform. template-sync-audit compares a consumer repo to the template and proposes improvements to backport. These skills make the governance system self-maintaining.
14. State Managementโ
State management is the layer that survives every interruption: laptop close, model upgrade, developer turnover, parallel sessions, machine swaps, crashes.
14.1 Three Storage Layers, Ordered by Authorityโ
Layer 1: The GitHub Issue body โ authoritative. Each in-progress task has a structured "AI Context" section in its GitHub Issue body. This is the source of truth.
Layer 2: The ClickUp custom field โ management mirror. When the AI persists context to the Issue body, it also writes a condensed version to a ClickUp custom field ai_context. This gives management dashboards visibility without granting them read access to GitHub Issues.
Layer 3: The local cache โ convenience. Per-machine cache at .claude/session/active-context.json. Used for fast resume in the same session. Always reconciled against the Issue body on session start.
14.2 The AI Context Block Structureโ
## AI Context (updated by Claude โ do not edit manually)
- **Active actor:** cc-ariel-laptop (Claude Code on Ariel's laptop)
- **Phase:** implementing (chunk 3 of 5)
- **Last updated:** 2026-05-17T14:32:00Z
- **Plan:**
1. Add UserBookingRepository (done)
2. Wire into BookingService (done)
3. Add unit tests for repository (in progress)
4. Add integration test (pending)
5. Open PR (pending)
- **Files touched:** apps/api/src/booking/{repository,service,booking.module}.ts, plus 4 test files
- **Decisions:**
- Chose Mongo over Aurora for booking history (volume + write patterns)
- Single-document booking model with embedded changes array
- **Blockers:** none
- **Next step:** Finish unit tests in booking.repository.spec.ts
The block is structured but human-readable. Any actor โ Claude on a different machine, a different developer, a manager checking on progress โ can open the Issue and understand the situation in thirty seconds.
14.3 Handoff Scenariosโ
Same person, mobile resume. Mobile Claude opens the Issue, reads the context, runs /continue. Identical experience.
Sick coworker handoff. Original developer (or the AI on their behalf) runs /handoff. The AI updates the Issue body with current state and tags the next actor. The next actor opens the Issue, runs /continue, and resumes.
Cross-machine same person. Identical to mobile resume.
Task complete. On /done, the AI proposes a final "AI Context" update that summarizes what was done, the linked PR, and any followups. This is the version managers and teammates see going forward.
14.3.1 State Reconciliation Algorithmโ
Mobile resume โ and more generally, any session start where the AI may have stale local state โ runs through a deterministic reconciliation algorithm. The algorithm exists because "trust whichever copy I happen to see first" is exactly how state corruption happens.
Step 1: Identify the candidate task. The AI determines which task is active. Three sources, in order of preference:
- The local cache
.claude/session/active-context.jsonif it exists and was modified within the last 24 hours. - The most recently updated open GitHub Issue assigned to the current actor with label
in-progress. - If neither, the AI presents the open ClickUp tasks and asks.
Step 2: Fetch both copies. If a candidate task exists, the AI fetches:
- The local cache (if present):
local_copywithlocal_updated_attimestamp. - The GitHub Issue body's "AI Context" block:
remote_copywithremote_updated_attimestamp parsed from theLast updatedfield inside the block.
Step 3: Apply the reconciliation rules.
if remote_copy does not exist:
# New task, no remote state yet
state = local_copy or initialize_empty()
elif local_copy does not exist:
# Fresh machine, new session, or wiped cache
state = remote_copy
write_local_cache(remote_copy)
elif remote_updated_at > local_updated_at:
# Remote is newer โ someone updated from another machine
# (mobile resume, coworker handoff, or different actor)
state = remote_copy
write_local_cache(remote_copy)
elif local_updated_at > remote_updated_at:
# Local is newer โ likely a crash before state-sync flushed
# Push local to remote, but verify no conflict
if remote_actor != local_actor:
# Different actor wrote remote; we cannot blindly overwrite
raise ReconciliationConflict(local_copy, remote_copy)
else:
# Same actor; safe to push local
write_remote(local_copy)
state = local_copy
else:
# Timestamps equal, take either (they should be identical)
state = remote_copy
Step 4: Handle reconciliation conflict. If different actors hold conflicting state, the AI does not silently merge. It stops and presents both copies to the user, asking which to take as canonical. The chosen copy becomes the new authoritative state. The conflict is logged for retrospective analysis (these should be rare; if they happen often, the lease mechanism is failing).
Step 5: Validate completeness. Before proceeding to step 4 of the autonomous loop, the AI checks the reconciled state for required fields: Active actor, Phase, Plan, Files touched, Next step. If any are missing, the AI asks the user to fill the gap before continuing. A half-state is worse than no state.
Step 6: Persist and proceed. The reconciled state is written to both local cache and remote Issue body (if the remote was outdated). The AI then proceeds with the autonomous loop, starting from the Next step.
14.4 The state-sync Skillโ
The state-sync skill runs in the background during long tasks. It persists the Issue body's "AI Context" every 30 minutes or every 3 commits, whichever comes first. The skill is non-blocking; if the network is down, the local cache absorbs the writes and flushes on reconnect.
The skill is in the "always silent" autonomy category. Persisting state is never gated.
15. Ownership and Leasesโ
The full lease design described in ยง15.3โยง15.6 โ a GitHub Issue lease store, 30-minute leases, 10-minute heartbeats, the lease-cleanup.yml scheduled workflow โ is not implemented. The store, schema, claim API, heartbeat skill, and cleanup workflow all wait for a dedicated implementation pass. Until then:
- The ClickUp assignee = task owner convention (ยง15.1โยง15.2) is the only lease-like mechanism actually in force.
- The multi-actor branch prefix (
cc-ariel/...) from ยง15.5 is not enforced by the currentbranch-name-check.sh(see ยง6.7). - Re-trigger for the lease work: when the lease infrastructure (store + schema + API) ships in whichever repo will own it.
Ownership and leases solve the claim race problem. They prevent two AI sessions from working on the same task in parallel.
15.1 ClickUp Assignee = Lease Holderโ
The ClickUp assignee field is the authoritative ownership record. If a task has one assignee, that person owns it. If a task has two or more assignees, ownership is ambiguous and the AI stops.
This decision avoids introducing a new state store. ClickUp already tracks assignees. We use it.
15.2 The Multi-Assignee Resolution Flowโ
When the AI sees a multi-assignee task at Step 2 of the autonomous loop:
AI: Task CU-1234 ("Booking flow refactor") is assigned to
both Ariel and Yossi. Which of you is doing the actual
implementation? The other should be removed as assignee
in ClickUp.
The user answers. The AI proceeds. The other assignee is removed in ClickUp (configurable gate, default autonomous since this is a routine status maintenance action).
15.3 The Working State Leaseโ
While a task is in progress, the AI also creates a GitHub Issue lease record. This is a GitHub Issue (in bewith-dev/bewith-docs) labeled ai-lease with body JSON describing the actor, the machine, the target repo, the target task, the branch, the claimed_at, and the expires_at. Lease duration: 30 minutes. The heartbeat skill renews every 10 minutes.
The lease is the "I am actively working on this" signal, separate from ClickUp ownership. The reason for the split: a developer can be assigned a ClickUp task that they're not currently working on. The lease signals current activity.
15.4 Stale Detection and Reclaimโ
A scheduled CI workflow lease-cleanup.yml runs every 15 minutes and closes lease issues whose expires_at is in the past. Once closed, the work is claimable again.
This handles "Claude crashed mid-session," "laptop ran out of battery," "network died for an hour." The lease expires, the cleanup workflow closes it, the next session can pick up.
15.5 Branch Naming for Multi-Actorโ
Branches always carry an actor prefix when multiple actors operate in the same repo: cc-ariel/{type}/{slug}_CU-{id} for Claude Code on Ariel's machine, cp-cloud/{type}/{slug}_CU-{id} for Copilot cloud, and so on. This prevents collisions on identical CU-id work from different actors.
The pre-push hook validates the branch name format.
15.6 The Heartbeat and Cleanup Mechanismโ
The lease system is a distributed lock with three moving parts: the claim (acquiring the lease), the heartbeat (proving the lease is still in use), and the cleanup (releasing dead leases). The mechanism is detailed in v0.3 ยง14.6 and unchanged here: 10-minute heartbeat, 30-minute lease, 15-minute cleanup schedule, Datadog metrics for observability.
16. Hard Gates: Hooks and CIโ
Hard gates are the tooling-level enforcement of the rules. They run regardless of whether the work came from Claude or a human.
16.1 Local Hooksโ
Hooks live in governance/.claude/hooks/ and are bound via governance/.claude/settings.json. They run on the developer's machine, in the Claude Code lifecycle. Hooks are also installed as git hooks (via husky or similar) so manual developers get identical enforcement.
16.1.1 Pre-Commit Hooksโ
These run before a commit is created. They block the commit on failure.
commit-cu-check.sh. Requires a CU-{id} substring in the commit message body or trailers. Works for both AI commits and manual commits.
branch-name-check.sh (also pre-push). Validates {type}/{slug}_CU-{id} or {actor}/{type}/{slug}_CU-{id} format per ยง6.7.
file-size-check.sh. Fails the commit if any staged file exceeds 500 KB (configurable per repo). Catches accidentally committed binaries, generated artifacts, and bloated assets.
no-master-edit.sh. Blocks commits directly to master, main, develop, or any release/* branch.
block-edit-on-master.sh (PreToolUse for Claude). The Claude-Code-specific version of no-master-edit. Blocks any Edit or Write tool call when the current branch is shared. Provides a clearer error message in the Claude conversation.
16.1.2 Pre-Push Hooksโ
These run before git push succeeds. They block the push on failure.
branch-name-check.sh (re-run on push).
tests-pass-check.sh. Runs the repo's scripts/test.sh. The hook supports a --changed-only flag for fast iteration; full test runs happen in CI.
typecheck-pass.sh. Runs scripts/typecheck.sh (typically tsc --noEmit or equivalent). Fails the push on type errors.
lint-pass.sh. Runs scripts/lint.sh (ESLint, Prettier check, PHP CS Fixer for legacy). Auto-fixable issues are reported but do not block; non-auto-fixable issues block.
16.1.3 Dangerous-Operation Hooks (PreToolUse, Claude-only)โ
These intercept Claude tool calls before they execute.
block-dangerous-git.sh. Blocks force-push to shared branches, git filter-repo, BFG, branch deletion of shared branches, git reset --hard on shared branches.
block-dangerous-bash.sh. Blocks shell patterns associated with destructive operations: rm -rf /, rm -rf ~, mongo --eval "db.dropDatabase()", psql ... "DROP DATABASE", etc. The pattern list lives in .claude/hooks/dangerous-patterns.json (JSON, not YAML โ see Implementation notes).
16.1.4 Session-Start Hooksโ
These run when Claude Code starts a session.
(removed) governance-build.sh lived here in the original plan โ it regenerated .claude/effective/ from the pinned platform plus local overlay. Deleted 2026-06-08 with the rest of the governance.lock model; under the plugin model there is no per-consumer .claude/effective/ to build (see ยง6.5).
mcp-availability-check.sh. Verifies that MCP servers declared in .claude/settings.json are reachable and authenticated. Failure produces a warning, not a block โ the AI proceeds with degraded capabilities and reports which MCPs are unavailable.
active-context-validate.sh. If .claude/session/active-context.json exists, validates that it parses correctly and references still resolve (branches exist, Issues are open). Stale references trigger the reconciliation flow in ยง14.3.1.
16.2 CI Workflowsโ
Workflows live in .github/workflows/ (not configs/github-workflows/ โ GitHub Actions's uses: resolver requires this path). Current cut: 4 reusable workflows + 1 platform-only + 2 dropped + 3 deferred. The rationale per workflow is captured in Implementation notes at the top of this doc.
Reusable (called by every consumer's wrapper):
branch-name-check.yml (reusable). CI mirror of git-hooks/branch-name-check.sh. Validates ${{ github.head_ref }} against the dual-mode regex; with require_cu_id: true, the _CU-{valid-id} suffix is mandatory and validated by scripts/checks/check-cu-id.sh; with require_cu_id: false (default), the suffix is optional but still validated when present. Needed because Copilot/mobile/manual PRs do not run the local git hook.
file-size-check.yml (reusable). CI mirror of git-hooks/file-size-check.sh. Fails a PR if any file changed in the diff exceeds the configured size limit (default 500 KB). Same rationale: local hook does not cover all PR origins.
clickup-commit-check.yml (reusable). Hard-gate on PR title for CU-id (validated by scripts/checks/check-cu-id.sh โ โฅ6 alphanumeric, โฅ1 digit, โฅ1 letter). Warns on commits without CU-id; the hard gate is the PR title because the title is the canonical reference an external reader (or ClickUp) sees.
(removed) governance-version-check.yml lived here in the original plan and in the interim 2026-05-26 design. Deleted 2026-05-27 with the rest of the lock contract โ see ยง6.4.
Platform-only:
governance-serialize.yml (not reusable). Allows only one PR open at a time touching 13 sensitive paths in this repo (.claude/, policies/, autonomy/, events/, etc.). Prevents governance drift from parallel edits.
Dropped โ won't build:
cross-impact-check.yml. DROPPED. Git's merge mechanism already catches text conflicts; the "awareness" use case is better served by Slack/CODEOWNERS auto-assignment than by CI warning noise. No incident has surfaced that this gate would have caught.
contract-impact-analysis.yml. DROPPED. Contracts (API specs, Zod schemas) are runtime/domain artifacts, not meta-governance โ they don't belong in this repo. The convention for handling contract changes is captured in policies/api-contract-change.yaml for downstream repos to adopt.
Deferred with re-trigger conditions:
test-quality-check.yml. DEFERRED. No consumer repos exist yet, so there is nothing to scan. Re-trigger when the first consumer repo with a real test suite onboards.
lease-cleanup.yml. DEFERRED. Depends on the lease-mechanism runtime (lease store, schema, claim API) that lives outside this repo and is not built. Re-trigger when the lease infrastructure ships.
ai-pr-review.yml. DEFERRED. Depends on (a) the code-reviewer agent (unbuilt), (b) a cloud-bootstrap mechanism for materializing the platform into a CI session (unbuilt), (c) Anthropic API secret. /ultrareview covers user-triggered review meanwhile. Re-trigger when both code-reviewer.md ships and the cloud-bootstrap mechanism is designed.
16.3 What Gates Do Not Enforceโ
Gates enforce mechanical correctness โ conventions, IDs, no force-push, no breaking contract without bump. They do not enforce design quality, test usefulness, product correctness, or business alignment. Those are the AI agents' job, validated by the code-reviewer agent on PR and the product-manager agent on spec.
16.4 Three Foundational Hard Rules in CLAUDE.mdโ
Beyond what hooks and CI can enforce, three hard rules live at the top of every CLAUDE.md (both the platform router and every consumer's local copy). These are non-negotiable behavioral rules that the AI is told to apply universally. They are the rules a hook cannot enforce because the violation is semantic, not syntactic.
16.4.1 Rule 1 โ Confirm Understanding Before Any Mutating Actionโ
Before performing any action that mutates user-visible state (file write, commit, push, comment, status change, deploy), the AI must confirm it has correctly understood the task. The bar: the AI can articulate, in its own words, what success looks like and what the user is asking for.
This rule prevents the most common failure mode: the AI takes a vague instruction, fills in the blanks with assumptions, and produces work that solves the wrong problem. The rule is satisfied by the planning step (Step 6 of the /continue loop) when there is a plan to approve; for ad-hoc actions outside the loop, the AI restates the goal before acting.
This rule does not require explicit human approval for every action โ that would re-introduce the friction we removed in ยง10. It requires self-confirmation: the AI demonstrates understanding, and proceeds. If the AI cannot articulate the goal clearly, it stops and asks.
The canonical wording is adopted into the platform's CLAUDE.md (when authored) and referenced by every agent that performs mutating actions.
16.4.2 Rule 2 โ Never Invent ClickUp IDs, Repo Names, or File Pathsโ
The AI must never fabricate a ClickUp task ID, a GitHub repository name, a file path, an environment variable name, an API endpoint, or any other identifier that resolves to a real resource. If the identifier is not in the conversation, in a tool result, or in the loaded context, the AI must stop and ask.
This rule prevents hallucinated references that look correct but point at nothing. The failure mode is severe: the AI writes a commit message referencing CU-9876 because the conversation discussed CU-9874 and the AI misremembered. A hook catches the missing CU-id in some cases but cannot validate that the ID exists in ClickUp. A wrong reference in a commit becomes wrong audit trail forever.
The enforcement is partly tooling โ mcp-preflight validates that referenced ClickUp tasks exist before commit โ and partly behavioral.
16.4.3 Rule 3 โ Tests Must Be Real and Meaningfulโ
The AI must not write tests that exist only to satisfy coverage requirements. For any behavioral code, the tests must exercise the real behavior with real assertions. Mocking is allowed only at the external boundary (third-party APIs, time, randomness). Mocking the domain service whose behavior is being tested is forbidden.
This rule addresses the most insidious form of test neglect: tests that exist but verify nothing. The AI is tempted to write expect(result).toBeDefined() because the coverage tool accepts it. The QA agent and the code-reviewer agent are loaded with this rule's anti-patterns. The full testing strategy is ยง17.
The rule is enforced partly in CI (a test-quality-check.yml workflow flags suspicious patterns: tests with no assertions, tests that mock the system under test, tests that only verify boilerplate) and partly by the agents.
These three rules are repeated at the top of every consumer CLAUDE.md. They are short enough to fit on a single screen. They cover the failure modes that the rest of the system addresses only indirectly.
16.5 Manual Developers Get Identical Enforcementโ
Every hook is installed as a git hook in the consumer repo. Every CI workflow runs on every PR. A developer who never opens Claude Code still gets the safety floor. This is the principle behind "manual workflows are first-class."
17. Testing Strategyโ
This section codifies the testing standard for every repo under governance. It is enforced by qa-engineer and code-reviewer agents, by test-quality-check.yml in CI, and by per-repo coverage configuration.
17.1 Guiding Principleโ
Test the contract, not the implementation. If a test breaks when an implementation detail changes without changing behavior, the test is noise.
- โ "When the user clicks X, then Y happens."
- โ "When function Z is called, the spy is invoked."
17.2 The Testing Pyramidโ
/\
/E2E\ 5-10 tests: critical user journeys only
/------\
/Integration\ 20-30% of test count: real DB + Redis + queues
/------------\
/ Unit Tests \ 70%: pure functions, validations, business logic
/----------------\
| Layer | Speed | Cost | Flakiness | When It Catches Bugs |
|---|---|---|---|---|
| Unit | <100ms | $ | Low | Before integration |
| Integration | 1โ3s | $$ | Medium | At system boundaries |
| E2E | 30sโ5min | $$$ | Higher | After deployment simulation |
ROI sweet spot: 70% unit, 25% integration, 5% E2E.
17.3 Coverage Targets per Layerโ
| Layer | Target | Rationale |
|---|---|---|
| Zod schemas | 100% | Critical contract surface, trivially testable |
| Business logic | 90%+ | The heart of the application |
| API endpoints | 80% | Integration tests cover request โ response |
| Frontend components with logic | 60โ70% | Only logic-bearing components; presentational components excluded |
| Utils / helpers | 85%+ | Pure functions are cheap to test |
| E2E | N/A | Coverage metric not meaningful here |
We do not chase 100%. 70% coverage of high-quality tests is better than 95% of noise.
17.4 Unit Tests โ Vitestโ
Framework: Vitest. Per-repo vitest.config.ts. Co-located *.spec.ts files next to the code under test.
What to test. Zod schemas, pure functions, business logic, custom hooks with logic, validators, formatters, permission checks.
What not to test. Getters/setters, pass-through functions, framework decorators (@Injectable(), useState), private methods (test via the public API).
Mocking โ external boundaries only.
Mock these: HTTP clients, LLM APIs (OpenAI, Gemini), email services, payment providers, file system, time, randomness.
Do not mock these: the database (use Testcontainers or mongodb-memory-server), Redis (use ioredis-mock or Testcontainers), your own domain services (call them for real), business logic (defeats the test's purpose).
Why? Mocks of internal code give false confidence. They pass when the code has real bugs.
17.5 Integration Tests โ Vitest + Testcontainersโ
Framework: Vitest with vitest.config.integration.ts + mongodb-memory-server (or Testcontainers for full MongoDB) + ioredis-mock (sufficient for most cases) or @testcontainers/redis when full Redis is needed.
Naming: *.integration.spec.ts. Files identified by suffix so they can be excluded from the unit run.
What to test. API endpoints (full flow: request โ validation โ DB โ response), queue processors (BullMQ job โ side effects โ DB changes), WebSocket handlers, transactions and rollbacks, complex queries (aggregations, joins, lookups).
Why Testcontainers > mocks. A mock repository will pass when:
- There is a unique index violation the mock did not model.
- A Mongoose middleware (hook) modifies the document on save.
- A transaction rolls back partial state.
- An aggregation pipeline returns the wrong shape.
- A race condition produces conflicting writes.
Real-database tests catch all of these. The CI cost is modest because integration tests run in their own job after unit tests pass (fail-fast).
17.6 E2E Tests โ Playwrightโ
Framework: Playwright. 5โ8 tests maximum per repo. Each test is a complete user flow.
The recommended set:
- Auth flow: signup โ verify email โ login โ logout
- Core entity CRUD: create โ view โ edit โ delete the primary resource
- Payment flow (if applicable): select plan โ checkout โ success
- Real-time feature (if applicable): send message โ see in other browser tab
- The one flow that defines the product's value
What NOT to put in E2E: every form validation (unit test), every edge case (integration test), UI states like loading/error (component test), permission variations (one role in E2E, rest in unit).
Playwright config conventions:
workers: 1in CI (less flakiness from parallel state).retries: 2in CI;0locally.trace: 'retain-on-failure',video: 'retain-on-failure',screenshot: 'only-on-failure'.- Mobile device profile only if the product has responsive-specific logic.
17.7 Visual Regression (Optional, Per-Repo)โ
For design-system repos and white-label SaaS, Playwright screenshots or Chromatic. Off by default; opt-in by the consumer repo via local overlay.
17.8 CI Strategy โ Fail Fastโ
jobs:
unit: # ~30s
integration: # ~2โ3min, needs: unit
e2e: # ~5โ8min, needs: integration, only on main + PRs
The needs: dependency means expensive tests do not run if cheap ones fail. Caching pnpm dependencies saves ~30s per run. Unit tests run in parallel by default. Integration and E2E run sequentially for determinism.
CI time budget per PR: โค 12 minutes. If a repo's tests routinely exceed this, the qa-engineer agent flags it for refactoring.
17.9 Test Quality Checklistโ
Before merging a test, the AI (and the human reviewer) must answer yes to all:
- Does it test behavior, not implementation?
- Will it fail if there is a real bug? (If renaming a variable breaks it, it is testing implementation.)
- Are we mocking only external boundaries?
- Is it fast enough? (Unit
< 100ms; integration< 2s; E2E< 30sper test.) - Does it have a clear failure message?
- Is it deterministic (no
setTimeoutwithout proper waits; no hardcoded "now"; no external API dependence in unit tests)?
If any answer is "no," the test does not merge as-is.
17.10 Why This Matters for AI-Assisted Developmentโ
The AI's biggest test-related failure mode is producing tests that pass but verify nothing. This is the form of test neglect that does the most damage because the coverage tool reports green. Without ยง17.9 enforcement, the team gets an illusion of safety.
test-quality-check.yml runs a heuristic classifier on every PR's test diff:
- Flags tests with zero
expect()/assertcalls. - Flags tests that mock a class then test that class's method.
- Flags tests whose assertions are only
toBeDefined()/toBeTruthy()without further qualification.
The classifier is advisory in Phase 4, blocking in Phase 6 (ยง20).
18. Release Managementโ
Releases turn merged PRs into deployed software. The flow has three phases โ develop integration, master cut, deploy โ each with its own gates.
18.1 The Branching Model (Consumer Repos)โ
bewith-dev consumer repos use a develop-master split:
developis the integration branch. Feature branches merge here via PR. CI runs the full test pyramid (ยง17.8) on every PR.masteris the deploy-ready branch. Code reaches master via release cut from develop.release/*branches are short-lived stabilization branches for a specific release. Rarely needed for non-shared repos; standard practice for libraries and shared services.- Tag pattern is environment-specific:
us-prod-{semver},fr-prod-{semver},staging-{semver}. The existingpr-deploy-labels.ymlworkflow inbewith-dev/.githubalready labels PRs as they pass through this flow.
18.2 The /release-cut Commandโ
A tech lead or release manager runs /release-cut. Claude:
- Identifies all merged PRs in
developsince the last tag. - Groups them by type: features, fixes, refactors, infra, docs.
- Drafts release notes from PR titles and ClickUp task summaries.
- Proposes a semver bump:
- Major if any merged PR carried a
breaking-changelabel. - Minor if any PR was a feature.
- Patch otherwise.
- Major if any merged PR carried a
- Opens a PR from
developtomasterwith the draft release notes as the body and the proposed tag in the title. - Pauses for the release manager's review and approval.
18.3 The /ship Commandโ
After the developโmaster PR is approved and merged, the release manager runs /ship. This is a Hard Floor action (ยง10.1.2) โ Claude pauses for explicit confirmation regardless of any developer's autonomy override.
The flow:
- Verify the local branch matches the merged master commit.
- Run the full verification suite once more.
- Bump the version file (e.g.
package.json) for deployable services. - Create the deploy tag (
us-prod-1.2.3or whichever the repo uses). - Push the tag.
- The deploy pipeline picks up the tag and runs.
watch-deployskill monitors it. - Datadog monitors are checked for 30 minutes post-deploy.
If Datadog flags an anomaly, /incident opens automatically and the release manager is paged.
18.4 Rollbackโ
/rollback <tag> is a Hard Floor action. It reverts to the prior tag, runs the same verification, and re-deploys. The release manager confirms each step.
18.5 Cross-Repo Releasesโ
When a feature spans multiple repos (frontend + backend + worker), the release cuts are coordinated by the eng-manager skill, which reads the linked ClickUp parent task and sequences the cuts in dependency order. Multi-repo releases are rare and explicit; the default is per-repo independence.
19. MCP Integrationsโ
The system integrates with the following Model Context Protocol servers:
| MCP | Purpose | Skills/agents that use it |
|---|---|---|
| ClickUp | Task management, comments, status, custom fields | clickup-task-load, clickup-comment-draft, daily-summary, eng-manager |
| GitHub | Issues, PRs, branches, releases, code search | All workflows touching GitHub |
| Confluence | Architecture docs, ADRs (mirror), runbooks (mirror) | confluence-page-draft, architecture-aware agents |
| Datadog | Logs, traces, metrics, dashboards, incidents | bewith-datadog-logs, log-investigation, analytics-observability agent |
| infra-mcp (sandbox) | Local Mongo/MySQL/Redis read access | sandbox-orchestrator, database agent, backend tasks |
| Postman | Collection management, request creation | postman-collection-builder |
| jam.dev | Bug report analysis (video, network, console) | jam-bug-analyzer |
Auth and availability are validated by the mcp-preflight skill, loaded automatically at step 4 of the autonomous loop and invoked at session start plus before any workflow that depends on a specific MCP.
When an MCP is unavailable, the AI does not silently fail. It either degrades gracefully (e.g., presents the cached version) or stops and reports the problem.
20. Migration Pathโ
The migration runs in six phases. Each phase is independently shippable. The system delivers value from Phase 3 onward.
20.1 Phase 0: Bootstrapโ
Create bewith-dev/bewith-docs as a real GitHub repository (not a local folder). Write this architecture document into it as governance/docs/BEWITH-AI-ARCHITECTURE.md. Create the empty folder structure. Tag bewith-docs VERSION = 0.1.0.
Duration: half a day.
20.2 Phase 1: Source Consolidationโ
Migrate prior conventions, agent specs, and prototype rules into the platform repo. The migration normalises content to the BeWith canonical agent template, the artifact-types framework, and the platform's single-SoT discipline. Once content has landed in bewith-dev/bewith-docs, the prior assets are archived.
Duration: two to three weeks.
20.3 Phase 2: Contracts and Configsโ
Populate governance/contracts/ with OpenAPI, Zod schemas, generated TypeScript and PHP bindings. Populate governance/configs/ with shared ESLint, Prettier, tsconfig, Vitest, commitlint, and reusable GitHub workflows.
This is mostly content migration from existing repos.
Duration: one week.
20.4 Phase 3: Pilot Three Reposโ
Choose three pilot repos: one backend service (backend-services), one frontend (management-webapp), one worker (sqs-consumer). Run install-to-consumer.sh for each. Fill in the local CLAUDE.md content. Build the effective/ directory. Open the first PR with the governance addition. Run a full feature through the autonomous loop in each pilot.
Collect feedback. Iterate on the platform. Tag bewith-docs VERSION = 0.2.0 once stable.
Duration: two weeks.
20.5 Phase 4: Org-Wide Rolloutโ
Apply governance to the ten highest-activity repos. Each takes about an hour with the install script. CI gates activate in bewith-dev/.github.
The remaining repos are added over the following month, prioritized by activity.
Duration: two weeks for the top ten, ongoing for the rest.
20.6 Phase 5: Knowledge Migrationโ
Populate knowledge/. Migrate Confluence content that is genuinely useful into version-controlled markdown. Confluence remains the source for content that is appropriate there (long-form documentation, meeting notes, customer-facing content). Engineering-relevant knowledge moves to the repo.
Confluence pages that previously held conventions are rewritten to be one-paragraph pointers to the canonical markdown in the repo, with a clear note: "The binding version of this convention lives at bewith-dev/bewith-docs/governance/CLAUDE.md. This Confluence page is a human-readable mirror updated weekly."
Duration: two weeks, depending on Confluence scope.
20.7 Phase 6: Hardeningโ
Promote ai-pr-review from informational to blocking on auth and contracts paths. Promote cross-impact-check from warning to blocking once precision data justifies it. Promote test-quality-check from advisory to blocking. Tighten policies based on what the team has learned. Add the overlay drift audit. Add the telemetry dashboard.
Duration: ongoing, with quarterly reviews.
21. Onboardingโ
21.1 Onboarding a New Repositoryโ
For any new bewith repo (template or existing):
- From the consumer repo's root, run
bash ~/.claude/plugins/cache/bewith/scripts/install-to-consumer.sh. Idempotent โ createsCLAUDE.mdand.github/copilot-instructions.mdif absent; touches nothing else. - Fill in placeholders in
CLAUDE.md(Project Overview, Tech Stack, conventions, deploy notes, domain glossary). - Add
.github/workflows/wrapper.ymlcalling the platform's reusable workflows byuses: bewith-dev/bewith-docs/.github/workflows/<name>.yml@vN.N.N. Pin to the platform version this repo certifies against. - (Optional) Drop
git-hooks/config.envat the repo root if you want a per-repoREQUIRE_*override (default toggles inherit from the platform). git add+ commit. Open the first PR to validate that CI gates trigger correctly. No build step; no.claude/effective/; no lock file.
21.2 Onboarding a New Developerโ
Day one:
- Clone the
sandbox, and the repos the new dev will work on. - Install Claude Code; authenticate.
- Run
bewith platform installfrom the sandbox CLI to register thebewithplugin and wirecore.hooksPathglobally. - Configure MCP servers in
~/.claude/settings.jsonperdocs/onboarding.md. - Run
/init-claudein any consumer repo โ validates MCP auth, GitHub auth, sandbox status, governance pin. - Run
/help-bewithfor the command list. - First task: shadow an experienced dev on a small task for about half a day.
First small task end-to-end:
The user is assigned a ClickUp task. The new dev runs /continue. The AI fetches the task, asks for confirmation, asks design-review or direct, plans, gets approval, creates the branch, implements with the dev's input, runs tests/lint/build, opens the PR, and on /done proposes the ClickUp status change. The dev observes every step and approves opt-in actions.
The dev learns the system by example.
22. Adoption Strategyโ
This section addresses the audience of this document directly: Aviad and the engineering team. The methodology is unfamiliar enough that explaining it as "here is the new way to work" produces friction. We frame adoption around three claims that the team can verify for themselves.
22.1 Claim 1 โ Nothing You Use Today Breaksโ
The existing tooling continues to work:
- Prior agent specifications are preserved verbatim; the rewrite to the BeWith canonical agent template normalises structure without losing content.
- Consumer repos opt in to the platform per repo via
install-to-consumer.shand thebewithplugin. A repo that hasn't onboarded yet is unaffected. sandbox/infrastructure (Mongo, MySQL, Redis local + launchd) is the basis forinfra-mcp. It does not change.
A developer who does nothing different the day after bewith plugin v1.0.0 ships sees no difference. Adoption is opt-in per repo.
22.2 Claim 2 โ The Guidance Becomes Better, Not Biggerโ
The risk in any governance addition is that the developer feels supervised. The architecture takes the opposite stance: the AI runs more autonomously after this lands, not less. Specifically:
- The Foundation rule (Confirm Understanding Before Mutating) is one prompt-level pause. It happens once per session, not once per action.
- The Hard Floor is six items. Production deploy, force-push, secret rotation, drop, public publish, CODEOWNERS. Everything else is autonomous by default. A developer can opt in to more gates; the platform does not force them.
- The state lives in GitHub Issues, which the developer already opens for their PRs. The AI Context block is structured but readable in 30 seconds. It is not new ceremony.
The result: a developer who runs /continue after the rollout types fewer messages per task, not more.
22.3 Claim 3 โ The Failure Modes the Team Knows Become Detectableโ
Every team member has stories of:
- An AI session that "forgot" a convention three messages in and made up a different one.
- A PR merged without tests because the AI didn't think to add them.
- Two developers who realized at code review that they were working on the same ticket.
- A schema change that broke a frontend nobody noticed until QA.
Each of these has a named gate in this architecture: lazy loading + agent files, test-quality-check.yml, lease system, contract-impact-analysis.yml. The team does not have to take the architecture's word for the improvement; we measure (ยง28) and report.
22.4 Why Nowโ
Three reasons.
First, the team is already paying the cost of the failure modes โ every duplicate implementation, every untested PR, every claim race is a real cost that the team has already absorbed. The cost of the architecture is one engineer-quarter for Phase 0โ3. The cost of not doing it is paid in perpetuity.
Second, the existing internal assets have drifted into several separate sources of truth. Each is incomplete on its own. The cost to consolidate grows monthly as each gets more content.
Third, the AI tools are getting better. The cost of not keeping the rules in tooling grows: a smarter model with better autonomy and worse alignment is more dangerous than a less smart model with better gates. We need the gates in place before we lean harder on the model.
22.5 What the CTO Conversation Looks Likeโ
The CTO question is, "what does this change for me and my team day to day?" The answer should be honest:
- For the agent author (Aviad): the existing agent specifications are preserved verbatim and get a single canonical home in
.claude/agents/. CODEOWNERS routes governance/agents PRs to him (or his designate). He no longer maintains agent files in a separate place that drifts from how the team actually works. - For the rules/skills author (Baruch): the existing rules, commands, and skills migrate into
bewith-dev/bewith-docsand become the platform-shipped path. His stewardship moves with the content โ same scope, single home. - For developers:
/continueworks the same way it does today, only more consistently. New commands (/status,/release-cut,/improvement-idea) appear over time. Per-repo customisation still works via the consumer overlay (project-scope.claude/shadows the plugin). - For Ariel: the prototype foundation rule + the destructive-ops taxonomy that became
autonomy/defaults.yamlship as platform content with credit in the change log.
The answer to "what changes" is "less than you might think, but the things that change become measurable."
22.6 The Hardest Pushbacks (Anticipated)โ
"This is over-engineered for a 10-person team."
The architecture is sized for 44 repositories, not 10 people. The fragmentation we have today is repo-level, not headcount-level. The federation and lazy loading exist to keep the cost-per-repo low; the architecture pays for itself by Phase 3.
"We don't have time to migrate."
Phase 0โ3 is six weeks. The work that produces the most ROI is in Phase 3 (pilot repos). After Phase 3, the team's daily work has the same accelerators it has today and a safer floor. The remaining phases are background work that doesn't block daily delivery.
"What if Claude or Anthropic changes and our investment is wasted?"
The architecture is methodology-first. The implementation choices (Claude Code, ClickUp, GitHub) are the current best mappings. If the model layer changes, the rules in YAML, the hooks, the CI workflows, the agents-as-markdown โ all of it survives. The only swap point is the runtime that reads the platform.
"We tried something like this before and it stalled."
The prior attempts were content (rules, agents, skills) without enforcement. This architecture inverts the priority: enforcement first (hooks + CI + Policy Engine), content second. The substantive content already exists across our internal sources; the platform's job is to give it teeth.
23. Day-to-Day Developer Experienceโ
This section is for engineers reading this doc and asking, "what does my day look like after Phase 3 ships?"
23.1 Monday Morningโ
Developer opens Claude Code. Types: "continue working" / /continue.
Claude:
- Reads the developer's local
CLAUDE.mdand the bewith plugin's installed version. Reports: "Loaded bewith plugin v0.1.0, backend-services consumer config, lazy mode." - Checks GitHub for an in-progress Issue. None today.
- Pulls ClickUp tasks assigned to the developer.
- Presents the list in chat with priorities, custom fields, links.
- Developer picks a task. Claude reads it.
- Foundation: "Understanding the task โ you want to add a CSV export endpoint to the bookings API. Acceptance criteria: admin role, scoped to current org, paginated up to 10k rows, returns 202 + job ID. To confirm I start?"
- Developer: "yes."
- Claude evaluates policies (no contract change, no schema migration, no auth touch). Loads
backend-developer,code-reviewer,process-guardian. - Drafts a plan in 4 chunks. Presents. Developer tweaks one detail. Approves.
- Claude acquires lease, creates branch
cc-ariel/feature/bookings-csv-export_CU-86c8aa123, implements chunk 1 with tests (Vitest unit + Testcontainers integration), commits. - Continues chunks 2, 3, 4. Each chunk: implement โ test โ commit. State-sync runs in background.
- Runs
verify.sh. All green. - Pushes. Opens PR. PR body includes the test plan, ClickUp link, what changed, what to verify manually.
ai-pr-review.ymlruns on the PR, posts code-reviewer findings.- Developer reads the AI review, accepts most, asks Claude to fix one nit. Claude commits a tiny fix.
- Developer pings a colleague. Colleague reviews and approves.
- Developer merges. GitHub Issue closes. ClickUp status moves to "Done" (autonomous; configurable).
watch-deploywatches the next deploy. Observability is clean (Datadog today, Loki/CloudWatch as it migrates).
Total elapsed: about three hours, of which Claude is at the keyboard for about 2:45 and the developer is reviewing for 0:15.
23.2 Tuesday Afternoon (Different Scenario)โ
Developer wants to propose a process improvement: "We should auto-link Datadog dashboards to PRs that touch instrumentation."
Developer types: /improvement-idea (or just states the idea).
Claude:
- Foundation: confirms understanding.
- Analyzes what exists: searches
bewith-docs/.claude/skills/, findsbewith-datadog-logsbut no PR-linking automation. Searchesbewith-dev-github/.github/workflows/โ no existing linker. - Reports back: "This doesn't exist today. There is a
bewith-datadog-logsskill that knows about Datadog auth, which would be the right base. Three options: (1) extend that skill to emit PR-comment templates; (2) add a new CI workflow inbewith-dev/.githubthat runs on PRs touching**/datadog*paths; (3) a custom dashboard component in the deploy bot. My recommendation is option 2 because it lands the value in the place the team already looks." - Developer: "let's open a personal backlog ticket."
- Claude creates a ClickUp task in the developer's personal "Ideas" list with a structured body.
- Returns the link.
Two weeks later, when the developer says "deep dive on CU-86c8xyzzz," Claude reloads the prior analysis, expands with risk/alternatives, and produces a one-page proposal the developer can post to the team channel.
23.3 Wednesday Mid-Morning (Status Check)โ
Developer types /status.
Claude:
Your week so far:
NOW
- CU-86c8aa123 โ Bookings CSV export โ PR open, awaiting review from @yossi
- CU-86c8bb456 โ Hotfix: invoice rounding โ blocked on finance answer, last update yesterday 16:00
TODAY
- CU-86c8cc789 โ Add filter chip to events list โ in plan stage, no branch yet
THIS WEEK
- CU-86c8dd012 โ Resident category subscribe flow โ assigned, not started
WATCHING
- PR-2451 in management-webapp โ awaiting your review since Mon AM
Developer pings Yossi about the open PR, replies on the finance Slack thread, and starts on CU-86c8cc789.
23.4 Thursday Afternoon (Teammate Status)โ
Tech lead asks: "where is Maya on the i18n rollout?"
Tech lead types /status @maya.
Claude pulls Maya's assigned tasks, open PRs, active leases. Reports tactically:
Maya โ open work:
NOW
- CU-86c8ee345 โ i18n keys for events page โ in implementation, branch
cc-maya/feature/i18n-events_CU-86c8ee345 last commit 47min ago
TODAY
- (nothing else in progress)
THIS WEEK
- CU-86c8ff678 โ i18n keys for resident profile โ not started
NOTES
- No leases older than 1 hour. No blockers reported.
Tech lead pings Maya only if needed. No standup interrupt.
23.5 Friday End-of-Dayโ
Developer types /daily-summary.
Claude drafts:
Today (Fri 22 May):
โ
Shipped: Bookings CSV export (CU-86c8aa123) โ merged 11:14, deployed 14:22
๐ In review: Filter chips on events list (CU-86c8cc789) โ PR opened 16:01
๐ซ Blocked: Invoice rounding (CU-86c8bb456) โ waiting on finance answer
๐ Started: Resident category subscribe flow (CU-86c8dd012) โ DR planned for Mon
๐ฏ Help wanted: Need someone to pair on the Cognito refresh-token edge case in CU-86c8dd012 sometime Mon AM
Developer pastes into the team standup channel. Five lines, factual, complete.
24. Conventions Live in Git, Not in Confluenceโ
Every binding convention lives as versioned markdown in bewith-dev/bewith-docs. Confluence is the human-readable mirror, not the source.
24.1 What Moves Out of Confluenceโ
- Branch naming conventions โ
governance/CLAUDE.md+governance/.claude/hooks/branch-name-check.sh. - Commit message format โ same.
- PR title format โ same.
- Code review guidelines โ
governance/agents/code-reviewer.md. - Tech stack version policy โ
governance/CLAUDE.md+governance/configs/. - Testing policy (this doc, ยง17) โ
governance/docs/testing-strategy.md. - Deployment runbooks โ
knowledge/runbooks/.
24.2 What Stays in Confluenceโ
- Long-form architecture narratives that benefit from being browsable by non-engineers (PM, support, customer success).
- Meeting notes, decision logs that are not ADRs (ADRs go in
knowledge/adr/). - Customer-facing or sales-facing content.
- Onboarding pages for non-engineering roles.
24.3 How Confluence Pages Are Rewrittenโ
Each Confluence page that previously held a convention is reduced to:
The canonical version of this convention lives at:
https://github.com/bewith-dev/bewith-docs/blob/main/governance/CLAUDE.md#branch-naming
This Confluence page mirrors the canonical source. It is updated
weekly by the bewith-docs CI. If you see a discrepancy,
the GitHub version wins.
A scheduled CI workflow (mirror-to-confluence.yml) updates the Confluence pages weekly. Drift is detected by config-audit skill.
24.4 Why Git Wins Over Confluence for Binding Contentโ
- Version history is real. Every change is a commit with author, timestamp, and (in a PR) reasoning.
- Diffs are visible. A reviewer can see what changed.
- Cross-references are validated. A markdown link to another doc breaks loudly if the target moves; a Confluence link breaks silently.
- CI can read it. Git-stored conventions can be parsed by hooks, CI, and the Policy Engine. Confluence-stored conventions cannot.
- The AI can read it. Claude operates on the git repo. Confluence access via MCP is slower, more brittle, and rate-limited.
25. Source-of-Truth Consolidation Planโ
Prior internal assets โ accumulated rules, agent specifications, and prototype workflows โ are migrating into this repo (bewith-dev/bewith-docs), which is the single SoT going forward. The detailed asset-by-asset mapping that lived here in the original plan is no longer maintained as a doc; in practice each migration commit carries its own scope. Once the migration finishes, the prior asset sources are archived.
The migration is content-preserving where possible (no rewrite for its own sake), normalised to the BeWith canonical agent template, and validated against the artifact-types decision tree.
bewith-dev/.githubcontinues to hold its existing reusable workflows (e.g.pr-deploy-labels.yml). The reusable workflows from ยง16.2 are added underbewith-dev/bewith-docs/.github/workflows/.sandbox/is the dev-machine data plane. It is referenced frombewith-docs/docs/mcp/infra-mcp.md. No content moves.
26. Extensibility and Governance Evolutionโ
26.1 Adding New Agents, Skills, Commands, Workflowsโ
Scaffolding scripts (and matching /new-* commands) reduce friction:
./scripts/scaffold-agent.sh <name>โ createsgovernance/agents/<name>.mdfrom template, updatesAGENTS.md../scripts/scaffold-skill.sh <name>โ createsgovernance/.claude/skills/<name>/SKILL.md../scripts/scaffold-command.sh <name>โ createsgovernance/.claude/commands/<name>.md../scripts/scaffold-workflow.sh <name>โ createsgovernance/docs/workflows/<name>.mdand adds it to the index../scripts/scaffold-policy.sh <name>โ createsgovernance/policies/<name>.yamlfrom template, updatesPOLICIES.md.
Each script opens an editor at the new file. The author fills in content and opens a PR. CI validates: frontmatter is correct, no duplicate names, references in CLAUDE.md, AGENTS.md, or POLICIES.md were updated where required.
26.2 The AI Requesting New Agentsโ
If the AI encounters a task where no existing agent has authority, it does not improvise. It stops and signals to the operating developer: "I don't have an agent for X. Should I draft one?"
If the developer approves, the AI drafts the agent against the BeWith canonical agent template and opens a PR to bewith-docs. The agent is reviewed and merged through the same flow as any other governance change.
This is the extensibility mechanism. The system grows from the gaps it discovers.
26.3 Governance Evolution via Meta-Skillsโ
Three meta-skills keep the governance itself maintained:
config-audit runs against the platform and reports drift, contradictions, out-of-date references, and orphaned files. It does not change anything; it produces a report.
governance-sync takes a config-audit report and applies the proposed fixes back to the platform. Each fix is a PR.
template-sync-audit compares a consumer repo to the template and proposes improvements to backport. A pattern that works well in one consumer can be promoted to the template.
These skills make the governance system self-maintaining. A monthly run of config-audit and a quarterly run of template-sync-audit keep the platform from rotting.
27. Manual-Friendly Workflowsโ
A developer who chooses not to use AI for a particular task gets:
- All local hooks: branch name validation, CU-id requirement, no master push, no force-push, file-size check.
- All CI workflows: cross-impact-check, clickup-commit-check, lint, test (with pyramid coverage), build, contract-impact-analysis.
- Conventional commits enforced by commitlint, with config from
governance/configs/. - ESLint, Prettier, Vitest config from
governance/configs/. - PR template requiring the same fields as AI-driven PRs (CU-id, test plan, screenshots).
The only thing manual devs miss is the productivity boost. The safety floor and the consistency are identical.
This is by design. The Governance Stack is an organizational system, not an AI feature. Treating it as either-or โ "you must use Claude" โ would fracture the team. Treating it as a shared floor on which AI is an accelerator preserves the choice and the standard.
28. Metrics and Telemetryโ
28.1 What We Measureโ
Token usage per task. Should stay roughly flat as the platform grows. If it climbs, lazy loading is not working.
Claim conflicts. Should approach zero. If it climbs, the lease system or the multi-assignee resolution is failing.
PR cycle time. Branch open to merge. Should decrease for AI-assisted PRs by 40โ50% versus baseline.
Test quality flags. PRs where test-quality-check.yml raised a flag. Target zero on merged PRs.
Tests forgotten. PRs that merge without test changes for behavioral changes. Target zero.
CU-id violations. Caught by hooks. Should be zero at the merge gate.
Cross-impact blocks. Should be low. High indicates coordination issues that may need policy or agent updates.
Governance lock lag. Distribution of how many versions consumer repos are behind the platform. Should be a tight cluster around the current or latest version.
Policy hit distribution. Which policies fire most often, which never fire. Inform pruning.
Autonomy override distribution. Which gates do developers most often enable. Inform whether a gate should be promoted to default-on.
Deploy regression rate. Datadog anomalies in the 30-minute window post-deploy, attributable to the change. Should be flat or decreasing.
28.2 Where We Measureโ
The daily-summary command can pull most of these from GitHub and ClickUp on demand. A governance/docs/METRICS.md document describes how to aggregate. A future Confluence dashboard pulls them weekly.
29. Risks and Mitigationsโ
| Risk | Mitigation |
|---|---|
| AI auto-posts to ClickUp without approval | Configurable gate; default off (autonomous), can be enabled per user |
| Federation build breaks on a developer's machine | Pure POSIX bash; tested on macOS, Linux, WSL |
| Overlay silently overrides platform | Build-time validation fails on redefinition |
| Distilling agents loses depth | Agents sized at 15โ25KB; lazy loading keeps cost manageable |
| State conflicts between local and remote | Issue body is SoT; local is cache; reconciliation on session start |
| Lease deadlock from crashed AI | 30-minute lease; heartbeat every 10 minutes; cleanup every 15 minutes |
| Manual devs bypass AI safety | Hooks and CI enforce regardless of who's at the keyboard |
| Hotfix skips too many gates | Explicit skip list and never-skip list in hotfix workflow |
| Sandbox unavailable | sandbox-orchestrator brings it up; mcp-preflight catches early |
| Legacy PHP gets aggressive AI changes | legacy-php-guide agent + policy + CODEOWNERS, three layers |
| Knowledge and Governance drift apart | Same repo, CODEOWNERS routes reviews separately, cross-refs validated by CI |
| Policy Engine becomes a black box | YAML is plain text and readable; CI can dry-run policies on a PR |
| Configurable autonomy gets misused | Hard floor cannot be disabled; the floor is the floor |
| Team perceives this as "yet another process change" | ยง22 adoption strategy: opt-in per repo, manual devs get same floor, measure and report |
| Tests pass but verify nothing | ยง17.10 test-quality-check.yml; agents loaded with Rule 3 |
| Confluence pages drift from Git canonical | mirror-to-confluence.yml weekly + config-audit detection |
30. Future Workโ
These are items deferred from v1:
- Promote
ai-pr-reviewfrom informational to blocking on specific paths (auth, contracts, infra). - Tighten
cross-impact-checkfrom warn to block once precision data justifies it. - Promote
test-quality-checkfrom advisory to blocking on PR merge. - Add overlay drift audit (alert if any overlay exceeds 30% of its parent agent).
- Add Slack MCP integration for status posts (with opt-in gate).
- Per-domain agent specialization if 15 agents prove insufficient.
- Mobile-first command refinement after measuring actual mobile usage patterns.
- Telemetry dashboard in Confluence pulling metrics weekly.
- Cost monitoring per repo, per developer, per session.
- Multi-language i18n agent if the platform expands beyond Hebrew + English.
- Product Domain workflows (Phase 2 of the domain hierarchy).
- Company Domain workflows (Phase 3 of the domain hierarchy).
- Visual regression standardization (Chromatic vs Playwright screenshots) once the design system stabilizes.
31. Appendicesโ
Appendix A: Glossaryโ
Actor. A specific AI session running on a specific machine. Example: cc-ariel-laptop.
Agent. A detailed expert knowledge file in .claude/agents/, 15โ25KB, written in the BeWith canonical agent template (see ยง12.2).
AI Context block. A structured markdown block in a GitHub Issue body that holds the authoritative state of an in-progress task.
Autonomy mode. The platform's default behavioral category for an action: always autonomous, configurable, or hard floor.
Configurable gate. An action class where the default is autonomous but each developer can opt in to require approval.
Consumer repository. Any of bewith-dev's 44 active repositories that consumes the bewith-docs platform via the bewith Claude Code plugin (installed once per developer) plus a per-repo wrapper workflow that pins the platform version with uses: bewith-dev/bewith-docs/.github/workflows/<name>.yml@vN.N.N.
CU-id. The ClickUp task identifier, e.g., CU-1234. Required in commit messages, branch names, and PR titles.
Effective directory. (Removed in the current implementation.) The original plan specified a generated .claude/effective/ folder per consumer, built from the pinned platform plus local overlay. Under the plugin model, the platform's content lives once in ~/.claude/plugins/cache/bewith/ on each developer's machine; no per-consumer materialization happens. See ยง6.5.
Event vocabulary. A markdown document listing the named events that policies can be triggered by. Not an event bus; a shared vocabulary.
Federation. The model where consumer repos adopt specific versions of the platform โ under the current plugin model, via the bewith plugin's version field plus each repo's wrapper-workflow @ref. No separate per-repo lock file.
Hard floor. An action that always requires explicit approval, regardless of any developer's configuration.
Lease. A GitHub Issue lease record indicating that a specific actor is actively working on a task.
Lazy loading. The practice of loading only the agents and skills the current task requires, not the full platform body.
Policy. A YAML file in governance/policies/ that maps events and file changes to required agents, gates, risk scores, and auto-workflows.
Policy Engine. The layer that evaluates all policies against the current task and aggregates the result.
Risk score. A number 1โ10 returned by a policy indicating the potential blast radius of a change.
Single Source of Truth (SoT). The one place a given piece of information lives. For task state, the GitHub Issue body. For ClickUp ownership, the ClickUp assignee. For governance rules, the platform repo.
Skill. A reusable AI capability, packaged as a SKILL.md file in its own directory.
Workflow. A procedural markdown document describing a multi-step process.
Appendix B: Example Policyโ
# governance/policies/schema-migration.yaml
id: schema-migration
name: Database Schema Migration
description: |
Triggered when a migration file is added or modified. Ensures the
migration is reviewable, reversible where possible, and tested
against the production-shaped sandbox before deploy.
triggered_by:
- file_change: "**/migrations/**"
- file_change: "**/*.migration.{ts,sql}"
risk:
score: 9
blast_radius: high
reason: "Schema changes are difficult to roll back in production"
required_agents:
- database
- backend-developer
- devops-infra
- code-reviewer
required_gates:
- id: migration_dry_run
description: "Run migration against sandbox; verify rollback path"
- id: data_loss_check
description: "Static analysis for DROP COLUMN, DROP TABLE, etc."
- id: index_review
description: "Verify any new indexes are justified and sized"
auto_workflows:
- on: migration_added
action: "open-issue-in-devops-repo-with-deploy-notes"
- on: data_loss_detected
action: "require-explicit-data-migration-plan"
human_approval_required:
- condition: "data_loss_detected"
- condition: "production_target == true"
Appendix C: Example Per-User Overrideโ
# ~/.claude/user-overrides.yaml
user: ariel
overrides:
schema_migration: on # I want approval on any schema migration
clickup_comment_post: on # I want approval before AI comments
cross_repo_pr_creation: on # I want approval on cross-repo PRs
Appendix D: The Routing Matrix at a Glanceโ
| Language | Layer | Agents loaded |
|---|---|---|
| TypeScript | Backend | backend-developer, code-reviewer, process-guardian |
| TypeScript | Frontend | frontend-developer, i18n-localization, code-reviewer |
| TypeScript | Database | database, backend-developer, code-reviewer |
| PHP | Legacy | legacy-php-guide, code-reviewer, process-guardian |
| SQL/Mongo | Database | database, devops-infra, code-reviewer |
| YAML/Terraform | Infra | devops-infra, code-reviewer |
| Markdown (ADR) | Architecture | architect, decision-recorder |
| Markdown (Spec) | Product | product-manager, architect |
| Test files | QA | qa-engineer, code-reviewer |
The Policy Engine produces the precise set for any given task; this table is the rough orientation.
Appendix E: Branch Naming โ Why Underscore Wonโ
Two formats were in use:
{type}/{slug}_CU-{id}(underscore form โ inCONVENTIONS.md).{type}/{slug}-(CU-{id})(parens form โ inpersonal-git-pr-conventions.mdc).
We picked underscore. Rationale:
- Shell escaping.
git checkout 'feature/foo-(CU-123)'requires quoting;git checkout feature/foo_CU-123does not. - CI YAML.
if: github.head_ref == 'feature/foo-(CU-123)'requires escaping in some YAML parsers; underscore form does not. - URL safety. Parentheses are percent-encoded in URLs (
%28/%29); underscores pass through. - Visual scanning.
_CU-reads cleanly ingit log --oneline;(CU-competes with parenthesized commit message conventions. - ClickUp linking is identical. ClickUp matches the
CU-<id>substring regardless of surrounding characters.
The underscore form is enforced by branch-name-check.sh as a pre-push hook. The parens form is removed from personal-git-pr-conventions.mdc during Phase 1 of the migration.
Appendix F: Test Quality Heuristicsโ
The test-quality-check.yml workflow flags these patterns:
- No assertions. Test function body has zero
expect()/assert/shouldcalls. - Trivial assertion. Only
expect(x).toBeDefined()orexpect(x).toBeTruthy()without a follow-up substantive check. - Mocked subject. Test imports class X and the test body mocks X's methods directly. Tests should mock dependencies of X, not X itself.
- Spy assertion. Assertion is purely
expect(spy).toHaveBeenCalled()with no behavioral check โ testing that "the code called the function" instead of "the function had the right effect." - Constant assertion. Test compares a value to a literal that's also computed in the test setup โ
expect(result.foo).toBe(input.foo)whereinput.foois just passed through.
The heuristics are advisory in Phase 3โ5 (CI comments only) and blocking in Phase 6.
Appendix G: NotebookLM Ingestion Notesโ
This document is structured for ingestion by Google's NotebookLM and similar tools:
- Sections are numbered for stable cross-reference.
- The executive summary (top) and ยง22 (adoption strategy) are the highest-density sources for presentation-style outputs.
- ยง1 (problem) and ยง29 (risks) give NotebookLM the contrast it needs for a podcast-style explanation.
- ยง23 (day-to-day) provides concrete walkthroughs that translate well to "here is what changes for you" slides.
Recommended prompts for NotebookLM:
- "Generate a 10-slide presentation summarizing this architecture for a CTO audience."
- "Create a 20-minute podcast script explaining what changes for engineers when this rolls out."
- "Write a one-page FAQ that answers the top five questions an engineer would ask after reading ยง22."
End of BeWith AI Engineering Architecture the current implementation
For questions or proposals to change this document, open an ADR in docs/adrs/ and a PR against this file.