Skip to content

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.yaml BEFORE 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, flag DEBT_WARNING and 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 new scripts/ 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/sse for 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, or info.yml:package)
  • Unowned code → ARCHIVE_CANDIDATE
  • Cross-team changes require GKG MCP query: gkg.bluefly.internal/mcp/sse BEFORE 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 apply model-config first, then agent

File / directory hygiene

  • No new top-level .md files at repo root
  • No new scripts/ dirs (use src/cli/ TypeScript or package.json scripts)
  • 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 to daily-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