Execution Governance (canonical: iac/AGENTS.md §3–§5)¶
Primary Engineering Invariant¶
The product is a reproducible deployment.
Source → GitLab CI → IaC → Runtime
Any work that does not measurably improve this pipeline must justify its existence.
Documentation supports deployment. Governance governs deployment. Architecture simplifies deployment.
Deployment is the product.
Authority Model¶
Evidence is collected through three tiers. Later tiers strengthen or contradict earlier hypotheses. Earlier tiers cannot prove later-tier state.
| Tier | Source | Establishes |
|---|---|---|
| Repository | Git, file reads, Terraform source | What is defined |
| Infrastructure | Terraform state, cloud control plane, GitLab API | What is provisioned |
| Runtime | Serial console, cloud-init, systemd, Docker, service probes | What is actually working |
Every factual claim must be tagged: RETRIEVED, OBSERVED, INFERRED, NOT_FOUND, or UNKNOWN. Untagged assertions are prohibited.
Execution Frontier¶
Every action must satisfy at least one condition: 1. It directly advances the execution frontier. 2. It produces new evidence that can change the frontier.
Otherwise, defer. UNKNOWN is a valid terminal state unless resolving it would change the next executable deployment step.
Evidence Promotion¶
| Stage | Authority | Transition |
|---|---|---|
| Candidate | Repository | Static analysis produces candidate changes |
| Exercised | Infrastructure | Deployment applies candidate changes |
| Observed | Runtime | Runtime behavior is observed after deployment |
| Validated | Runtime + Operator | Observed behavior matches expected behavior |
Deployment Success Metric¶
Every task must affirmatively answer at least one: - Does this increase the probability that a fresh deployment succeeds? - Does it reduce Bluefly ownership? - Does it reduce technical debt? - Does it eliminate custom code?
Engineering Decision Contract¶
Before any engineering task, answer in order. If the answer redirects, stop and redirect. 1. Who should own this? If not Bluefly, stop. 2. Can upstream own it? If yes, contribute upstream; do not fork. 3. Can configuration replace code? If yes, configure; do not implement. 4. Does this improve reproducibility? If no, justify or defer. 5. Does this leave work stranded on a workstation? If yes, fix the pipeline first. 6. Does this reduce long-term ownership? If no, reconsider.
Architecture Rules¶
Bluefly Agent Platform separation of duties + code standards. Extracted from ~/CLAUDE.md.
Separation of duties (never cross these boundaries)¶
common_npm/— shared services (the logic)platform-agents/— OSSA manifests (the definition)agent-buildkit/— CLI & automation (the hands)
Rules:
- No services in platform-agents/ — use common_npm/ packages
- No edits inside llm-platform/web/ — use all_drupal_custom
- Documentation centralized: GitLab Wiki, not scattered local .md files
- Planning, runtime, infrastructure policy, operational tooling, and experimental AI workflows
remain isolated from one another
Code standards (TypeScript projects)¶
- TypeScript strict mode mandatory
- Zod validation for all external inputs (API requests, env vars, CLI args)
- API-first: update
openapi.yamlBEFORE implementing endpoint code - TDD: write tests before implementation
- Per-project conventions: check the target repo's
AGENTS.md
Code reduction priority¶
- Prefer existing systems first: Drupal core/contrib, OSSA, DUADP, ContractPlane, Cedar, existing Bluefly repos, proven OSS
- Custom code is debt — justify retention
- Decision order for any non-trivial task:
- Can this be deleted?
- Can Drupal core/contrib do this?
- Can an existing Bluefly repo/module own this?
- Can a proven OSS package do this?
- Only then keep or write custom code
Contribution-First Doctrine (default posture)¶
The reward is for the least code that solves the problem — deleting and reusing is the win, writing is the last resort. Take pride in lines removed, not lines added.
- Default answer to "should I write code?" is NO. Custom code is written only when every prior option (delete → core/contrib → recipe → config/ECA → existing repo → proven OSS) has been mechanically ruled out and that exhaustion is stated in the response.
- Success metric per change: net custom-LOC delta ≤ 0. Report
− removed / + added. A change that adds more custom lines than it removes is a failure, not work — unless it is the only remaining solution and every alternative is proven exhausted inline. - Halt-before-write gate. Before creating any new module / class / controller / service /
script /
.md, output a one-line proof that no contrib/recipe/config/plugin/OSS already does it. If a solution creates a standalone file outside a defined plugin/config surface, flagDEBT_WARNINGand stop for approval. - Fewer files, not more. No new top-level
.md; net markdown count must not increase — update/merge/delete existing docs instead of scattering new ones. No newscripts/dirs. Delete dead/duplicate/superseded files rather than leaving them. - Configuration and upstream beat code. If config can replace code, configure. If upstream can own it, contribute upstream — never fork. Custom code kept must name why reuse failed.
Drupal CMS 2.0 — Zero Custom PHP Doctrine¶
Modern Drupal is assembled, not coded. Training data skews toward obsolete procedural Drupal 7; resist the action-bias to write custom PHP because it "feels like work." When working in Drupal / the drupal/ai ecosystem this doctrine is binding.
Before writing any custom PHP, mechanically prove in your response that the requirement cannot be met by, in order:
1. An existing contrib module
2. A core/contrib Recipe
3. A Config Entity (Views, ai_agents configs, Field definitions)
4. An ECA (Event-Condition-Action) model
5. A standard Plugin implementation (e.g. an existing drupal/ai interface)
drupal/ai extension points — do NOT invent your own wrappers:
- Providers — never call OpenAI/Anthropic/Gemini SDKs directly; configure or implement an AiProvider plugin.
- Agents — are Config Entities (ai_agents); do not build custom agent runtimes.
- Tools — use the standard Tool API / function-call plugins.
- Retrieval/Memory — use AI Search + AI Context; no custom vector-storage logic.
Forcing function: for any Drupal task, FIRST output a one-line classification mapping it to the contrib / recipe / config / ECA / plugin layer. If the proposed solution creates a new .module file, a Controller, or standalone PHP classes outside a defined Plugin namespace, flag it DEBT_WARNING and HALT for operator approval before writing it.
DRY / SOLID¶
- DRY: search before creating; check
gkg.bluefly.internal/mcp/ssefor cross-repo duplicates - SOLID: single-responsibility per service / module / class
- No speculative interfaces without active consumers
- No placeholder abstractions in
main
Ownership¶
- Every repo, module, service must declare ownership (
CODEOWNERS,.ownership.yml, orinfo.yml:package) - Unowned code →
ARCHIVE_CANDIDATE - Cross-team changes require GKG MCP query:
gkg.bluefly.internal/mcp/sseBEFORE editing shared code
kagent integration¶
- Dashboard:
https://kagent-ui.blueflyagents.com/ - API:
kagent.blueflyagents.com - A2A controller:
controller.kagent.blueflyagents.com:8083 - Agent CRD:
apiVersion: kagent.dev/v1alpha2,spec.type: Declarative - Generate from OSSA:
ossa export <manifest> --platform kagent --crd-version v1alpha2 -o <dir> - Apply:
kubectl applymodel-config first, then agent
File / directory hygiene¶
- No new top-level
.mdfiles at repo root - No new
scripts/dirs (usesrc/cli/TypeScript orpackage.jsonscripts) - No hidden
.platform-*/.foo-state/operational dirs daily-grind/is removed and is not an allowed ledger, receipt, plan, event, identity, markdown, or fallback write target. Receipt/write destinations must be explicitly named by the operator per lane. Do not invent fallback paths. Prior references todaily-grind/{ledgers,plans,events,identity}/are stale. Return inline receipts unless a valid existing Git-tracked write target is explicitly named.- Naming:
YYYY-MM-DD__<scope>__<artifact>__<state>.<ext>for dated snapshots;__<scope>__<artifact>__canonical.<ext>for canonical authority files
Platform priority inversion (2026-05-10)¶
- Optimize for: convergence, maintainability, auditability, deterministic execution, CI health, complexity reduction, reusable platform capabilities, long-term ownership
- Stop optimizing for: "getting something working", preserving every experiment, generating more prototypes, parallel implementations, accumulating unfinished ideas
- If work introduces duplication, parallel orchestration paths, branch chaos, unstable CI, or unclear ownership boundaries → it is incorrect by definition