Be Civic — System Specification

Repo: hk121992/be-civic-specs — carved from bc-operations/specs/ 2026-05-21. See CLAUDE.md for amendment workflow and agent instructions.

Status: v0.5 design draft (post 2026-05-12 amendments — Path Directory concept: paths schema §6.12, requires_paths frontmatter block, path MCP tools §23.2.1, path rendering §20.11–§20.12, path source rot §11.1, path draft trust gate §7; genericity sweep on touched subsections) Last updated: 2026-05-12 Owner: Henry Kernot (founder; per S47) Round-6 source of truth: ../docs/design-conversation-r6-canonical-collapse.md — 49 scenarios (S1–S49) decided 2026-05-03 driving the architectural collapse, the licence change, and the commercial posture Press release: ../docs/product-vision/press-release.md v4 (commit 50c25d3) — customer-facing crystallisation of the round-6 vision Section G source of truth (round-5 prior decisions, retained for audit): ../docs/archive/round-6/spec-validation/open-questions-for-henry.md (G.1–G.14, plus D.1 / D.3 redirects) — architectural decisions from the 2026-04-26/27 design sessions, retained as historical reference where round-6 did not supersede

Overview

Be Civic is a public corpus at becivic.be of skills consumed by personal AI agents to help users complete Belgian government admin tasks. Operated by an independent company publishing under CC-BY-4.0; funded through a provider-integration protocol layer that is out of scope at v1.

The corpus is not a wiki, a how-to site, or a flowchart. It is a small, citation-grounded set of skills plus the conventions, staging service, status state machine, and consensus-validation flow that let it grow and self-correct over time. The interesting research bet is the consumer-AI-authored corpus protocol: how consumer AIs file structured submissions from real use, how a staging service holds and screens those submissions, how subsequent consumer-AI validators reach consensus on proposed changes, and how skills and catalogue rows advance through a deterministic state machine (draft → alpha → beta → stable) without a maintainer in the normal loop.

A user's personal AI agent loads a relevant skill from this repository, combines it with the user's specific context, and produces situated guidance — citing statutory hooks, listing required documents, naming failure modes, and ending with a "verify with your commune" checklist. After the user completes the task, the agent files structured submissions back to Be Civic anonymously, fuelling the corpus-growth protocol.

The maintainer is a constitutional court — handling injection-flag quarantines, NER-flagged held submissions, skill_draft PR review, provider-eligibility decisions, and protocol amendments — not a per-PR reviewer for routine corpus growth.

Sub-spec index

This monolithic specification was split on 2026-05-11 (v0.4) into eight documents for navigability. Each document is self-contained but cross-references siblings explicitly in its final "Cross-references" section.

Doc Covers
architecture.md Principles (§3), architecture overview and system diagram (§4), repository layout (§5), reference consumer and agent interface (§13, §13.1), anti-patterns (§16), settled decisions (§17), open questions (§18), out-of-scope items (§19), consumer-side runtime — two-layer skill model, skills-graph, capability tiers, onboarding (§24)
protocol.md Trust model and contribution tiers (§7) including path_draft review gate; citation rot and path source rot cross-reference (§11); provider-integration protocol layer (§21) including deferred Path Directory provider interface; MCP server (§23) including Path Directory MCP tools (§23.2.1): get_path_directory, get_path, submit_path_source_validation, submit_path_amendment, submit_path_draft
schemas.md All JSON schemas: skill frontmatter (§6.1) including new requires_paths: block; all four submission schemas and analytics endpoint (§6.2); volatile values (§6.3); communes data file (§6.4); skills index and activity dashboards (§6.5) including paths index; skill composition graph (§6.6) extended to path IDs; agent capabilities (§6.7) including path-consumption tier; scrub rules file (§6.8); schema version compatibility (§6.9) extended to path catalogue; MDX-tag conventions (§6.10); catalogue UID convention (§6.11) including pth-NNNNN prefix; Path Directory schema (§6.12) — path entries, source entries, source classes, actor block, eligibility predicates, validation path templates, oneOf/if-then constraints
privacy.md PII protection: trust boundary (§8.1), submission contract (§8.2), receiving-end ingestion pipeline (§8.3), Cloudflare reference implementation (§8.4), NER held-for-review path (§8.5), incident response (§8.6), consumer-side state contract and 16-axis profile.json (§8.7), retention and deletion semantics (§8.8), document-content-discard rule (§8.9), anonymous-by-construction structural reinforcement (§8.10)
lifecycle.md State-machine promotion (§9) with promotion thresholds, rollback, and quarantine mechanics; branch policy and retraction (§10); path source rot — periodic probing, last_validated, deprecation cascade (§11.1); test fixtures (§12)
skills.md Skill-drafting protocol and drafting steps (§15.1–§15.6), harness consumer obligations (§15.7), skill body discipline (§15.8), OSS-alignment frontmatter (§15.9); requires_paths: block — path declarations in skill frontmatter, role, timing, selects_on, notes
website.md Website rendering substrate (§20): hosting model, renderer architecture, runtime hooks, brand decisions, pages in scope; path rendering — becivic.be/paths/ index and per-entry pages, predicate prose translation, actor-block handoff display, lifecycle badges (§20.11); requires_paths display in skill rendering — "Documents and tools you will need" section, purpose badges, timing notes (§20.12); multi-site monorepo (§22) including note that paths live at bc-docs/paths/index.json

Adjacent files (not part of the v0.4 split; leave untouched):

File Role
cowork-plugin.md Cowork-harness-specific contract — the first delivery surface. Covers what the Cowork plugin bundle ships, the filesystem layout, plugin-specific bootstrap and onboarding details. Sibling files (chatgpt-app.md, etc.) will live alongside as other harnesses come online. Formerly v1-spec.md (renamed 2026-05-18 ahead of multi-harness expansion).
build-tools.md Internal build-tools specification (separate from the product spec): bc-corpus-creator, research-report.md schema, evals.json schema, and product-spec integration points. Cross-referenced from schemas.md and skills.md where product behaviour intersects with build-tool artefacts.
site-copy-r1.md Marketing copy for the landing page
seo-indexing-checklist.md SEO launch checklist
archive/specification-pre-rewrite-2026-05-03.md Pre-rewrite monolith (round-5 / early round-6 era)
archive/specification-pre-split-2026-05-11.md Post-rewrite, pre-split monolith (v0.4 before this split)
amendment-proposals/ Draft proposals to amend the spec, pending reconciliation into the canonical spec files. See amendment-proposals/README.md for the workflow. Reconciled proposal: amendment-proposals/2026-05-12-path-directory-concept.md (Path Directory — reconciled into spec v0.5 on 2026-05-12).

§1 Purpose

A public corpus at becivic.be of skills consumed by personal AI agents to help users complete Belgian government admin tasks. Be Civic is operated by an independent company that publishes the corpus under CC-BY-4.0; the company funds its work through a provider-integration protocol layer (§21 in protocol.md) — out of scope at v1, in scope as v1.x ambition. The corpus is not a wiki, a how-to site, or a flowchart. It is a small, citation-grounded set of skills plus the conventions, staging service, status state machine, and consensus-validation flow that let it grow and self-correct over time.

The interesting research bet is not the skills themselves but the consumer-AI-authored corpus protocol: how consumer AIs file five kinds of structured feedback (concern, amendment, validation, draft, feedback) — plus the parallel rating channel — from real use, how the staging service holds and screens those submissions, how subsequent consumer-AI validators reach consensus on proposed changes, and how skills, paths, and catalogue rows advance through a deterministic state machine (draft → alpha → beta → stable; rollback and quarantine via D1 supersession or git revert, history preserved) without a maintainer in the normal loop. (Pre-2026-05-15 the framing was "four submission types" — observation, skill_amendment, skill_draft, validation; the v0.6 taxonomy normalization collapses the route-shaped types into the type-shaped 5 + 1.)

The maintainer (founder, in customer-facing voice; per S47) is a constitutional court — handling injection-flag quarantines, NER-flagged held submissions, draft PR review (target_type=skill | path), operator-private feedback triage, provider-eligibility decisions (§21 (see protocol.md)), and protocol amendments — not a per-PR reviewer for routine corpus growth.

§2 Vision

A user's personal AI agent has access to that user's documents, context, and preferences. When the user faces an admin task (citizenship application, permit renewal, mutuelle enrolment), the agent loads a relevant skill from this repository, combines it with the user's specific context, and produces situated guidance — citing statutory hooks, listing required documents, naming failure modes, and ending with a "verify with your commune" checklist.

After the user completes (or attempts) the task, the agent files structured feedback back to Be Civic (post-2026-05-15 taxonomy):

  • Concerns capture negative signals — something is wrong on a specific artefact, or the agent could not route to one. Anchored to target_type ∈ {skill, volatile_value, reference, path, path_source, skill_graph}. Pre-2026-05-15 these were observation submissions with an event_type discriminator.
  • Amendments propose targeted edits. Unified across target_type ∈ {skill, volatile_value, reference, path, path_source}. Skill body and frontmatter edits open PRs; VV / Ref corrections take a fast-path D1 INSERT-with-supersede. Pre-2026-05-15 these were skill_amendment and path_amendment separately.
  • Drafts propose entirely new artefacts. target_type ∈ {skill, path}. Maintainer review is required (one of the few human-review gates remaining in the protocol).
  • Validations are verdicts — confirm or reject — from subsequent consumer AIs that have run the proposed change against real user sessions. Validations cover six target_type values including upvotes/downvotes on committed concerns (target_type='observation' — the wire surface name preserved per locked OPEN-13).
  • Feedback is the free-text channel about Be Civic itself (bug, suggestion, praise, confusion, accessibility) — no target_type. Operator-private triage queue; no public surface.
  • Ratings (Lock A, sprint 2026-W23) — opt-in three-axis stars: skill_quality_stars per skill, agent_protocol_stars per protocol version, user_experience_stars per session.

Validations from consumer AIs are the corpus-growth mechanism. An artefact (skill body, volatile-value row, reference row) advances through draft → alpha → beta → stable based on confirms, rejects, distinct submitter IPs, and elapsed time. Maintainer review is reserved for skill_draft PRs (new skills), quarantines (injection-flag triggered), PII held by NER, provider-eligibility decisions (§21 (see protocol.md)), and protocol amendments. Normal corpus growth runs without the maintainer.

This is the protocol. The scope for v1 is all Belgian government processes (federal, regional, communal). Expansion to other countries or non-government domains is explicitly out of scope for now — the architecture allows it (the umbrella becivic.be and the composition graph are general), but the project does not pursue it. Belgium is the focus.

§14 Initial deliverables and sequencing

Sequence is deliberate — schemas + protocol before skills, infrastructure before content, one skill exercising the full loop before scaling.

End-state-first (per S51): the round-6 architecture (D1 catalogues + signals, MDX-tag resolution at build time, automated state machine, intent-oriented MCP, agent-interface compression, multi-site monorepo scaffold) ships in v1, before walks resume. The earlier v1 / v1.x split (round-6 hedge that deferred D1, MDX-tag resolution, and state-machine automation) is collapsed: every architectural component below ships before the corpus scales.

Capability Where it ships
One canonical.md per skill (file-collapse) v1
status enum unified (draft / alpha / beta / stable) v1
origin field (be-civic / community) v1
Submission endpoints with target_type keying v1
D1 storage of catalogues, observations, validations, votes v1
MDX-tag resolution at build/fetch time (<VV> / <Ref> / <Observations>) v1
Automated state machine (PR-opening + auto-merge; cron tick reading D1) v1
History API endpoints (S36) v1
Self-rendered Cloudflare Worker site (replaces Mintlify; bare apex) v1
Multi-site monorepo (core/ + sites/<site-id>/; per-site wrangler.toml) v1
Agent interface compressed (/agents ~40 lines + manifest.json + per-endpoint pages) v1
Dedicated MCP Worker at mcp.becivic.be (createMcpHandler; ~6 intent tools + path tools) v1
bc-docs privatised v1
Path Directory V0 catalogue (~7–8 entries: nationality-application document graph + casier judiciaire) at bc-docs/paths/index.json; path schema at bc-docs/schemas/path.schema.json; harness wiring to traverse sources per algorithm (§6.12 (see schemas.md)) v1 (friend-tester bundle)
Path rendering at becivic.be/paths/ and becivic.be/paths/<path_id> (§20.11 (see website.md)) v1 (friend-tester bundle)
Provider-integration protocol layer (§21 (see protocol.md)) v1.x ambition

The implementation plan that lifts the round-6 file-collapse baseline into the architecture above (D1 schema, Worker rewrites, multi-site restructure, MCP server, agent-interface split, automated state-machine cron, bc-docs privatisation) is a separate plan, drafted on top of this spec rewrite. Walks resume only after that plan lands.

v1 deliverables

Phase 0 — infrastructure setup (one-time, before any code):

  1. Domain registration — buy becivic.be (~€8/yr), point DNS at Cloudflare nameservers
  2. Cloudflare account — sign up (free), add becivic.be as a zone, configure SSL
  3. GitHub App creation — create be-civic-staging-bot (or similar) GitHub App with Contents: Read/Write permission, install on the Be-Civic/be-civic repo, generate private key, store in Cloudflare secrets
  4. Branch protection on skills/** — protect main such that all skill-touching changes go through PRs; the state-machine bot identity is allowed to merge state-only PRs (frontmatter status flips) on CI green; skill_draft PRs require maintainer review (S31)

Phase 0.5 — Self-rendered site setup (replaces former Mintlify hosting block per S50):

  1. Renderer scaffoldbc-infra/site/renderer/ Cloudflare Worker with Static Assets binding; markdown→HTML build pipeline; Pagefind static search index; light/dark theme; mobile drawer; TOC active-tracking; HTMLRewriter beacon injection; _redirects build-time deduplication (per S57)
  2. Initial docs.json — navigation source-of-truth read by the renderer (bc-infra/site/renderer/src/nav.ts); replaces former Mintlify schema dependency 6a. Multi-site monorepo scaffoldsite/core/ (shared rendering primitives, build pipeline, Worker scaffolding) + site/sites/becivic/ (per-site config, theme, content scope, wrangler.toml); future verticals instantiate as new entries under sites/ (per S55) 6b. MCP Worker scaffoldmcp.becivic.be Worker using createMcpHandler; ~6 intent-oriented tools wrapping becivic.be/api/* (per S54)

Phase 1 — schemas and protocol:

  1. Schemas frozen — one per submission type plus the skill schema (skill.schema.json, observation.schema.json, skill-amendment.schema.json, skill-draft.schema.json, validation.schema.json, communes.schema.json, regex-rules.schema.json); Path Directory schemas (path.schema.json, path-source.schema.json at bc-docs/schemas/)
  2. Type system files (schemas/types.json, schemas/categories.json, schemas/source-classes.json) — source-classes.json covers the Path Directory source-class closed enum (§6.12 (see schemas.md))
  3. Communes data (initial fetch from REFNIS, pinned nomenclature_date)
  4. Submission contract v1 (docs/submission-contract-v1.mdx) — covers all four submission types; capability self-classification; alpha/beta UX; pre-flight validation; opt-out
  5. Canonical detector rules (tools/scrub/regex-rules.json)
  6. Cross-ref + state-machine + categories audit scripts (tools/scripts/validate-cross-refs.ts, state-machine-tick.ts, regenerate-docs-json.ts, audit-categories.ts)
  7. Test fixtures (tests/fixtures/) — at least the invalid set across all four submission types, before validators are written
  8. Drafting protocol artefacts — the two meta-skills (meta-draft-l1-skill, meta-decompose-process) and prose entry pages (index.mdx, agents.mdx)

Phase 2 — staging service:

  1. Cloudflare routing topologysite/router-worker.js routes becivic.be/api/* to the staging Worker and becivic.be/* (everything else) to the renderer Worker (S50, S56). Bare apex only; no www subdomain. Renderer serves the marketing landing and all human-facing paths.
  2. Staging Worker (api/) for the four POST endpoints — observations, skill-amendments, skill-drafts, validations; plus DELETE / GET status per type
  3. Scheduled Worker (tools/staging-worker/) — cron commit job writing to the appropriate paths per submission type
  4. Worker deployment Action (.github/workflows/deploy-worker.yml)
  5. Synthetic round-trip on staging KV — POST one of each submission type, verify staging, commit, dedup, cancel, capability rejection, self-validation rejection, identity-field rejection

Phase 3 — repository CI and state machine:

  1. State-machine bot (state-machine.yml + tools/scripts/state-machine-tick.ts) — runs on a 5–15 min schedule (and on D1 webhook when available); queries D1 aggregates; opens PRs flipping skill status frontmatter or directly UPDATEs catalogue rows in D1; auto-merges PRs on CI green (except skill_draft PRs)
  2. Cross-reference validator wired to PR-CI
  3. Skills index Action (skills-index.yml) — status / origin / lifecycle aware
  4. Activity dashboard Action (activity-dashboard.yml)
  5. NER on commit Action (ner-on-commit.yml) — held-for-review path, NOT auto-revert
  6. Issue templates (skill-error-report.yml, bug-report.yml)

Phase 4 — first skills and Path Directory V0:

  1. Main skill #1 — drafted using meta-draft-l1-skill. Selection per docs/skill-corpus-plan.md; should be the simplest main skill so the end-to-end flow exercises the state machine without composition complexity.
  2. End-to-end live test — load the skill via a capable consumer, walk through the actual process, file observations, file at least one validation, watch the proposal advance through the state machine
  3. Main skill #2 — moderate complexity per corpus plan; tests branching-in-body and the skill_amendment path
  4. Main skill #3 — most complex per corpus plan; surfaces sub-skill needs via drafting, exercises the skill_draft path
  5. Sub-skills — drafted in the order determined by step 29 discoveries 30a. Path Directory V0 catalogue — author 7–8 path entries at bc-docs/paths/index.json covering the nationality-application document graph (7 entries: certificat-residence-historique, marriage-certificate-belgian, composition-de-menage-belgian, birth-certificate-belgian, id-card-residence-permit-copy, federal-registration-fee-receipt, employment-account-individual) plus casier-judiciaire as the 8th entry. Use the Round-2 portal harvest at bc-operations/docs/2026-05-12-portal-catalogs/ as the source-data input. 30b. Skill amendment — nationality-application — update nationality-application/canonical.md to add the requires_paths: block (§6.1 (see schemas.md)) referencing the V0 catalogue entries. Verify the cross-reference validator passes. 30c. Harness wiring — update the Be Civic harness to consume the paths catalogue and traverse sources per the agent algorithm (§6.12 (see schemas.md)). Includes consent gate for audited_document_delivery: true sources. 30d. Path renderer — implement becivic.be/paths/ index and per-entry pages (§20.11 (see website.md)) in the renderer build pipeline.

Phase 5 — observability and maintenance:

  1. Citation linkcheck Action (citation-linkcheck.yml)
  2. Communes refresh Action (communes-refresh.yml) — quarterly schedule
  3. Activity dashboard pages — render docs/activity/global.json to a renderer-served page (/docs/activity or similar)

Phase 6 — documentation and contributor docs:

  1. Contributor docs (CONTRIBUTING, skill-conventions, agent-guidelines, retraction-protocol) — documenting what already works
  2. README — last, once the system is real

Phase 1.1 / v1.1 — deferred:

  • Optional learning-from-observations job (extracting volatile-value drift, document-list updates from observation clusters into skill_amendment submissions). Architecture in §9.4 of lifecycle.md; not built in v1.
  • Switch-mutualité L1 (per D-vision.1 default)
  • Public health page (per F.13)
  • Stress-test regression suite (per F.16)

The drafting protocol (step 14) gates all subsequent skill work. Phase 4 is research-driven; each main skill drafting pass identifies its own sub-process needs.

Test users

After Phase 4 deliverables 26–27 land, recruit 5–10 test users with varied origin countries (US, India, UK, France, etc.) and varied agent platforms across the four ecosystems. Their submissions form the first real corpus and the first real validation traffic. Their feedback shapes v1.1 and any contract / schema iteration.

Anti-pattern explicitly avoided: writing conventions docs before skills exist. Conventions extracted from working skills avoid theoretical drift.

Status

v0.6 (2026-05-15). Feedback taxonomy normalised; S61 reversed; auto-version-bumping ships; rating type added (Lock A, sprint 2026-W23). Three amendments land:

  • amendment-proposals/2026-05-15-feedback-taxonomy-normalization.md — 10 route-shaped submission types collapse into 5 type-shaped feedback types (concern, amendment, validation, draft, feedback) + analytics + rating. Each typed feedback type carries target_type as the sole discriminator. The unified amendment covers skill / volatile_value / reference / path / path_source. The unified draft covers skill / path. New concern with target_type=skill_graph replaces the prior event_type=skill_surface. The <Observations> aggregator walks the canonical body's <VV>/<Ref>/<Path> inline tags and surfaces concerns + pending amendments across every cited uid. <CohortStats> is render-time-derived from D1 (NOT materialised in canonical frontmatter; locked G4). Hard pre-launch cutover; no aliases, no dual-write windows. Spec sites: schemas.md §6.2 (rewritten), §6.5, §6.7, §6.9, §6.10, §6.12.0 / §6.12.8 (sweeps); protocol.md §7, §11, §23.2; privacy.md §8.3, §8.4 routes, §8.4b, §8.5, §8.7.7, §8.10.1; lifecycle.md §9.1, §9.2 (cohort_anchor), §9.3 step 5, §9.6, §10.1 (Rule 15 + Rule 17 added; Rule 16 dropped per G4), §10.2, §11.1; skills.md §15.1, §15.6, §15.7 obligation 12; architecture.md §3 diagram, §17 (S84, S85, S86 added; S61 marked reversed), §G.1; website.md §20.11 / §20.12 (sweeps); build-tools.md and v1-spec.md (sweeps).
  • amendment-proposals/2026-05-15-auto-version-bumping.md — auto-version-bumping workflow per state-machine status (0.0.x draft / 0.1.x alpha / 0.2.x beta / 1.0.x stable; patch increments per commit; only minor+ bumps reset cohort). All 8 OPENs locked at proposal-author recommendations (per operator directive 2026-05-15). Spec sites: schemas.md §6.1 + §6.12 path parity; lifecycle.md §9.2 (cohort_started_at semantics), §9.3 step 5 (bundle with status PRs), §9.7 (new), §10.1 (Rule 15 auto-bump consistency check on the diff). See settled-decisions S87.
  • amendment-proposals/2026-05-13-inline-path-and-skill-tags.md — Phase 0 dependency for the taxonomy normalization. The routing_risk portion is annotated as partially superseded by the 2026-05-14-risk-framework (which landed earlier); the rest of the amendment applies: <Path> and <Skill> inline body tags defined in schemas.md §6.10; cross-reference from §6.1; authoring obligation in §15.1 step 9; PR-CI inline-tag resolution invariant in §15.8 invariant 10. Hard dependency on this enables the renderer aggregator's path-source surfacing.

S61 (the 2026-05-11 cluster-2 decision proposing an opaque recovery_token as the per-row recovery key) is reversed pre-launch. The recovery_token component never landed in code; the spec carried a 5-site contradiction with the live session_id recovery endpoint. Pre-launch reversal: session_id remains the recovery key end-to-end. Five spec sites reverted; the cluster-2 amendment doc carries a partial-reversal banner. See settled-decisions S85.

v0.5 (2026-05-12). Path Directory concept reconciled from amendment-proposals/2026-05-12-path-directory-concept.md (decisions D1–D26). Amendments land in: schemas.md (§6.12 new, §6.1/§6.2/§6.5/§6.6/§6.7/§6.9/§6.11 extended — authored by the schemas sub-agent); protocol.md (§7 path_draft trust gate, §11 source rot cross-reference, §21.7 deferred provider interface, §23.2.1 path MCP tools); website.md (§20.11 path rendering, §20.12 requires_paths display, §22 paths-in-monorepo note); lifecycle.md (§11.1 source rot — authored by the lifecycle sub-agent); skills.md (requires_paths block — authored by the skills sub-agent). Genericity sweep applied to all touched subsections (see D23). Status block, sub-spec index, and §14 deliverables updated here.

v0.4 (2026-05-11). Split from the monolithic specification.md. The 2026-05-11 amendments covered: observation taxonomy collapse (S59), /api/analytics endpoint (S60), session_id → recovery_token (S61 — reversed v0.6, 2026-05-15), harness consumer obligations (S62), consumer-side runtime tier model (S63), live-served skill-graph (S64), skill body discipline (S65), consumer-side state contract (S66), spec cross-reference gate (S67), and OSS-alignment frontmatter (S68).

The pre-split monolith is archived at archive/specification-pre-split-2026-05-11.md. The pre-rewrite v0.3 monolith (round-5 / early round-6 era) is archived at archive/specification-pre-rewrite-2026-05-03.md.