4+1 Development View¶
The Development View captures what FCC looks like to a developer. It
answers: which subpackages exist, which ones import from which, and
what happens between pip install -e . and a functioning CLI. Where
the Logical View names the classes and the
Process View traces their interactions, this page
is the map of the repository on disk.
The three diagrams below show the package layout of src/fcc/, the
allowed dependency layers, and the build pipeline from source to
runnable CLI.
Package layout¶
src/fcc/ is a flat-ish namespace package with 22 top-level
subpackages in v1.3.7. Each subpackage is a single responsibility: the
personas/ package knows nothing about protocols, the protocols/
package holds no compliance logic, and so on. Cross-cutting concerns
(events, tracing, metrics) live in their own packages so any other
package may import them.
Figure 1 shows the top-level subpackage map with the primary dependency arrows.
flowchart TD
subgraph Core["Core contracts"]
personas[personas/]
workflow[workflow/]
scenarios[scenarios/]
end
subgraph Runtime["Runtime"]
simulation[simulation/]
protocols[protocols/]
collaboration[collaboration/]
end
subgraph CrossCutting["Cross-cutting"]
messaging[messaging/]
observability[observability/]
end
subgraph Capabilities["Capabilities"]
search[search/]
knowledge[knowledge/]
rag[rag/]
federation[federation/]
objectmodel[objectmodel/]
end
subgraph Governance["Governance and evaluation"]
governance[governance/]
compliance[compliance/]
evaluation[evaluation/]
end
subgraph UserFacing["User-facing"]
scaffold[scaffold/]
dashboard[dashboard/]
demos[demos/]
tutorials[tutorials/]
audit[audit/ -- v1.3.6]
admin[admin/ -- v1.3.6]
end
personas --> workflow
workflow --> scenarios
scenarios --> simulation
simulation --> protocols
simulation --> collaboration
messaging --> simulation
messaging --> compliance
observability --> simulation
objectmodel --> federation
search --> rag
knowledge --> rag
governance --> compliance
evaluation --> compliance
personas --> scaffold
personas --> dashboard
personas --> demos
personas --> audit
personas --> admin
audit --> compliance
admin --> dashboard
The v1.3.6-new audit/ and admin/ packages consume the vendored
ecosystem registries at src/fcc/data/ecosystem/ directly, which is
why they sit at the outer layer: they aggregate lower layers into
operator-facing surfaces.
Dependency layers¶
The subpackages above fall into four dependency tiers. Core contracts sit at the bottom; cross-cutting concerns and capabilities sit in the middle; user-facing tools sit on top. No tier imports upward.
Figure 2 makes the layer invariant explicit and shows where
audit/ and admin/ land.
@startuml
package "Tier 0 — Core contracts" as T0 {
[personas]
[workflow]
[scenarios]
}
package "Tier 1 — Runtime" as T1 {
[simulation]
[action_engine]
}
package "Tier 2 — Cross-cutting + Capabilities" as T2 {
[messaging]
[observability]
[search]
[knowledge]
[rag]
[federation]
[objectmodel]
[governance]
[compliance]
[evaluation]
}
package "Tier 3 — Protocols + User-facing" as T3 {
[protocols]
[collaboration]
[scaffold]
[dashboard]
[demos]
[tutorials]
[audit]
[admin]
}
T1 ..> T0 : depends on
T2 ..> T0 : depends on
T2 ..> T1 : depends on
T3 ..> T0 : depends on
T3 ..> T1 : depends on
T3 ..> T2 : depends on
note right of T3
audit/ and admin/ (v1.3.6+) are top-level
consumers of the vendored ecosystem
registries under src/fcc/data/ecosystem/
end note
@enduml
Violations of this layering fail CI before they reach main. The tier boundary is deliberately wide at Tier 2 so that capabilities like RAG or semantic search can share cross-cutting messaging and observability without creating a cycle with governance.
Build pipeline¶
From a fresh checkout, pip install -e . runs setuptools which reads
pyproject.toml, wires entry points, and installs the wheel metadata.
At import time PersonaRegistry.load_directory() scans
src/fcc/data/personas/ for YAML files and PluginRegistry.load_all()
enumerates the fcc.plugins entry-point group declared by installed
packages. The CLI bootstraps from there.
Figure 3 traces the pipeline from source to fcc --help.
flowchart LR
A[pip install -e .] --> B[setuptools reads pyproject.toml]
B --> C[Install wheel metadata]
C --> D[Register entry points]
D --> E[import fcc]
E --> F[PersonaRegistry.load_directory]
F --> G[WorkflowActionRegistry.load]
G --> H[PluginRegistry.load_all via entry_points]
H --> I[VocabularyProviderPlugin probes]
I --> J[click CLI bootstrap]
J --> K[fcc --help ready]
The whole boot sequence is typically under 400 ms on a warm cache, which is fast enough that the CLI feels like a native tool rather than a Python application.
Dependency rules in practice¶
Always allowed: importing from Tier 0 (personas, workflow,
scenarios) from any other tier; importing from
messaging/ or observability/ from anywhere; importing from
fcc._resources for path resolution instead of computing paths from
__file__.
Conditionally allowed: Tier 2 packages may import from each other
as long as the resulting import graph remains acyclic — for instance,
rag/ imports from both search/ and knowledge/, which is fine
because neither imports from rag/.
Never allowed: any Tier 0 module importing from Tier 1, 2, or 3;
any direct Path(__file__) manipulation; any import of a protocol or
user-facing subpackage from a compliance or evaluation module.
The entry-point section of pyproject.toml is the integration
contract: plugins and vocabulary providers declare themselves under
fcc.plugins and fcc.vocabulary_providers respectively, and the
PluginRegistry honours only those entry points. That means a third
party can ship an FCC plugin without modifying this repository at all.
See also¶
pyproject.toml—[project.entry-points]sections forfcc.pluginsandfcc.vocabulary_providerssrc/fcc/_resources.py— centralized resource path resolutionsrc/fcc/personas/registry.py:62—PersonaRegistry.load_directorysrc/fcc/plugins/registry.py—PluginRegistry.load_allsrc/fcc/data/ecosystem/plugin_dependencies.yaml— plugin dependency audit file- Logical View
- Physical View
v1.5.0 Development Impact¶
v1.5.0 added two new top-level subpackages and extended four existing ones. The "flat-ish namespace" shape is preserved; the package count grows modestly and the allowed dependency layers do not change.
New subpackages: src/fcc/archive/ (POLARIS re-export, 1 module) and
the fcc.api stable surface (a flat re-export module at
src/fcc/api.py that collects the public v1.5.0 promotion paths).
Extended subpackages:
| Subpackage | Additions (v1.5.0) | Tier |
|---|---|---|
src/fcc/rag/ |
graphrag.py (682 LoC, Pillar B) |
Capabilities |
src/fcc/collaboration/ |
crdt.py (~450 LoC), multi_user.py (~515 LoC), Pillar D |
Runtime |
src/fcc/federation/ |
bidirectional.py (~400 LoC), Pillar E |
Capabilities |
src/fcc/knowledge/ |
lyra_bridge.py re-export (Pillar B sibling) |
Capabilities |
src/fcc/messaging/ |
lanes.py (PAOMBus, UXBus, LaneRouter, ADR-006) |
Cross-cutting |
src/fcc/search/ |
incremental.py (Pillar F) |
Capabilities |
src/fcc/compliance/ |
memoization.py (Pillar F) |
Governance + evaluation |
New front-end scaffolding (Pillar C, owner-approval gated):
frontend/src/i18n/ with English baseline + FR/ES/DE scaffolds;
docs/i18n/ companion doc tree; mkdocs-static-i18n plugin wired in
mkdocs config. All three ship with {{TRANSLATE_*}} markers pending
owner-approved translation cycles.
New scaffolding scripts (Pillar A, owner-approval gated):
publications/scripts/seed_canonical.py implements the canonical seed
data download; activation requires
--i-understand-external-license-implications.
Dependency rules are unchanged. The two new Protocols
(CRDTBackend, PolarisBridgeProtocol / LyraBridgeProtocol) live in
their respective subpackages and do not need to move to plugins/
because they are structural (not ABCs). The fcc.api.* surface imports
from the Capabilities and Runtime tiers but never the other way around.
v1.6.0 Impact¶
v1.6.0 does not add a new top-level subpackage inside src/fcc/; it
executes three pillars that v1.5.0 scaffolded. The development-view
footprint grows under publications/scripts/, scripts/, and
docs/i18n/, plus one ADR addition and one Python module whose
behaviour changed without a file move.
New scripts (outside src/fcc/, inside the repo):
| Path | Purpose | Pillar |
|---|---|---|
publications/scripts/fetch_canonical_seeds.py |
Owner-gated canonical seed downloader; writes seed_canonical_manifest.json + smoke substitutions |
A |
publications/scripts/seed_canonical.py |
Per-vertical CanonicalSource registry + dry-run manifest generator (v1.5.0 scaffold, stabilised in v1.6.0) |
A |
publications/scripts/puppeteer-config.json |
Chromium sandbox config for mmdc; the args block disables /dev/shm and sandbox to unbreak the make pub-diagrams deadlock |
Publications / ADR-014 |
scripts/verify_glossary_preservation.py |
CI gate — every do-not-translate glossary term must appear verbatim in every locale JSON | C |
scripts/verify_codename_decoder.py (v1.6.2) |
Ecosystem-docs gate — every row in docs/ecosystem/codename-decoder.md resolves to a real local path or the "not cloned locally" sentinel |
Ecosystem docs |
New data / docs artifacts:
docs/i18n/glossary.csv— four-column CSV (term, English baseline,do_not_translate, notes) consumed by the preservation verifier.frontend/src/i18n/locales/{en,fr,es,de}/common.json— four locale JSON files;{{TRANSLATE_*}}markers from the v1.5.0 scaffold are resolved in v1.6.0 by the translator sub-agent.publications/_output/seed_canonical/<vertical>/*— the committed canonical corpora (smoke-substituted in v1.6.0 bootstrap; real fetches tracked per-file via thesubstitutedflag).docs/ecosystem/seed-canonical-license-notices.md— per-corpus attribution authority; every downstream redistributor MUST preserve the attribution block from this file.
ADR-014 addition. docs/decisions/ADR-014_chromium_sandbox_puppeteer_config.md
(Accepted 2026-04-24) records the decision to standardise on
publications/scripts/puppeteer-config.json for every mmdc invocation
in make pub-diagrams. The dev-view consequence is that contributors
never touch /dev/shm or Chromium sandbox flags directly — the config
file is the single knob. See the Process View's "How the async story
fits together" section for how this interacts with the
parallel-worker cap for mermaid rendering.
Module whose behaviour changed without a file move.
src/fcc/knowledge/lyra_bridge.py still re-exports from
fcc.plugins.v1_5_preview.lyra_bridge, but the v1_5_preview module
itself is removed in v1.6.0 (the re-export target moves into
fcc.knowledge.lyra_bridge proper). Callers who still import from the
preview path get ModuleNotFoundError; callers who used the stable
path across v1.5.x are unaffected.
Dependency rules are unchanged. The three v1.6.0 scripts are not
importable Python modules inside src/fcc/; they are repo-level CLI
entry points driven by make targets. No tier boundary moves; no new
fcc.plugins.* namespace is introduced.