34 — Forgeyard Monorepo Intelligence, Dependency Graph, Affected-Change & Incremental Execution System Architecture
Document type: Core Monorepo Graph, Dependency Intelligence, Change Impact & Incremental Execution System Architecture
Project: Forgeyard CI/CD
Subsystem: workspace discovery, project/package graph, build-target graph, source ownership, dependency impact, affected-target detection, changed-file analysis, incremental planning, selective builds/tests, graph snapshots, cache-aware execution, cycle handling, graph queries, monorepo scale, and policy-safe optimization
Architecture style: Exact immutable source snapshots, deterministic graph construction, explicit dependency semantics, conservative impact analysis, derived graph intelligence, policy-controlled skipping, strong cache integration, and no silent correctness reduction
Status: Target production architecture extending the Forgeyard series beyond the original 01–26 plan
Relationship to prior work: Builds on VCS-neutral source snapshots, Pipeline IR, Scheduler, CAS/cache, Test Intelligence, Benchmarking, Search/Analytics, Change Proposal, RBE, language/ecosystem adapters, and hermetic/reproducible builds. This subsystem adds large-repository intelligence without making source analysis authoritative for security or policy.
1. Purpose
Modern repositories often contain:
many Rust crates
multiple services
shared libraries
desktop/mobile applications
frontend packages
infrastructure
documentation
test utilities
generated code
native components
A large monorepo cannot efficiently run every possible build and test for every small change.
Users need answers such as:
what changed?
which packages own those files?
which targets depend on them?
which tests are affected?
which release artifacts may change?
which jobs can safely be skipped?
which cached results remain reusable?
The central rule is:
Forgeyard computes affected work from an immutable source snapshot and a versioned dependency graph, but impact analysis is an optimization layer—not an unquestioned correctness authority.
A second rule is:
If Forgeyard cannot prove that a target is unaffected, the conservative answer is that it may be affected.
A third rule is:
Policy decides whether affected-only execution is acceptable for a given workflow. Stable releases may require broader validation than ordinary Change Proposals.
2. Architectural Position
SourceSnapshotId
│
▼
Workspace Discovery
│
▼
Dependency Graph
│
┌───────────┼───────────┐
▼ ▼ ▼
Files Targets Tests
│ │ │
└───────────┼───────────┘
▼
Change Impact
│
┌───────────┼───────────┐
▼ ▼ ▼
Direct Reverse Policy
Changes Dependents Expansion
│ │ │
└───────────┼───────────┘
▼
Incremental Plan
│
▼
Pipeline / Scheduler
3. Goals
The subsystem MUST:
- discover workspace structure;
- model packages/components;
- model build targets;
- model dependencies;
- model file ownership;
- model generated-source relationships;
- support multiple ecosystems;
- support monorepos;
- support polyglot repositories;
- support graph snapshots;
- support changed-file detection;
- support direct impact;
- support reverse dependency expansion;
- support test impact;
- support artifact impact;
- support pipeline impact;
- support graph queries;
- support incremental planning;
- integrate with cache;
- support policy expansion;
- support conservative fallback;
- support graph invalidation;
- support cycles;
- support large graphs;
- support distributed indexing;
- support graph diff;
- support visibility rules;
- support ownership;
- support standalone/distributed modes;
- remain rebuildable/derived.
4. Non-Goals
This subsystem does not:
replace Cargo/Bazel/CMake/npm/etc.
replace package managers
replace VCS
replace policy engine
replace scheduler
guarantee perfect semantic impact analysis for arbitrary code
5. Workspace Structure
crates/graph/
├── forgeyard-graph/
├── forgeyard-graph-model/
├── forgeyard-graph-discovery/
├── forgeyard-graph-build/
├── forgeyard-graph-query/
├── forgeyard-graph-diff/
├── forgeyard-graph-impact/
├── forgeyard-graph-cache/
├── forgeyard-graph-policy/
├── forgeyard-graph-reconcile/
├── forgeyard-graph-health/
└── forgeyard-graph-testkit/
Ecosystem graph adapters:
ecosystems/
├── rust/
│ └── graph/
├── go/
│ └── graph/
├── python/
│ └── graph/
├── javascript-typescript/
│ └── graph/
├── java-kotlin/
│ └── graph/
├── dart-flutter/
│ └── graph/
├── swift/
│ └── graph/
├── c-cpp/
│ └── graph/
└── native/
└── graph/
Use modules first; separate crates only when ecosystem/tool dependencies justify.
6. Repository Graph Identity
#![allow(unused)]
fn main() {
pub struct RepositoryGraphId(Digest);
}
Content-derived from:
SourceSnapshotId
graph schema version
discovery adapters
configuration
7. Graph Schema Version
#![allow(unused)]
fn main() {
pub struct GraphSchemaVersion(u16);
}
8. Graph Node
#![allow(unused)]
fn main() {
pub enum GraphNode {
Workspace(WorkspaceNode),
Package(PackageNode),
Target(TargetNode),
TestSuite(TestSuiteNode),
Artifact(ArtifactNode),
File(FileNode),
GeneratedSource(GeneratedSourceNode),
Custom(CustomGraphNode),
}
}
9. Graph Edge
#![allow(unused)]
fn main() {
pub struct GraphEdge {
pub from: GraphNodeId,
pub to: GraphNodeId,
pub kind: DependencyKind,
}
}
10. Dependency Kind
#![allow(unused)]
fn main() {
pub enum DependencyKind {
Build,
Runtime,
Test,
Development,
Tool,
Codegen,
Data,
Configuration,
GeneratedFrom,
Produces,
Owns,
Custom(DependencyKindId),
}
}
11. Direction
Define clearly:
A -> B
means A depends on B.
Reverse traversal gives affected dependents.
12. WorkspaceId
#![allow(unused)]
fn main() {
pub struct WorkspaceId(Digest);
}
13. PackageId
Graph package identity separate from release PackageId.
Use distinct name if collision:
#![allow(unused)]
fn main() {
pub struct SourcePackageId(Digest);
}
14. BuildTargetId
#![allow(unused)]
fn main() {
pub struct BuildTargetId(Digest);
}
15. FileNodeId
Derived from repo-relative path + SourceSnapshotId context.
16. Stable Logical Target
A logical target can have a stable key across snapshots.
17. TargetLogicalId
#![allow(unused)]
fn main() {
pub struct TargetLogicalId(Digest);
}
Derived from normalized workspace/package/target identity.
18. Why Two IDs
TargetLogicalId
tracks history.
BuildTargetId
binds exact graph snapshot/config.
19. File Ownership
#![allow(unused)]
fn main() {
pub struct FileOwnership {
pub file: RepoRelativePath,
pub owners: Vec<GraphNodeId>,
pub confidence: OwnershipConfidence,
}
}
20. Ownership Confidence
#![allow(unused)]
fn main() {
pub enum OwnershipConfidence {
Exact,
Declared,
Inferred,
Unknown,
}
}
21. Exact
Manifest/build-system mapping.
22. Declared
Forgeyard config.
23. Inferred
Heuristic.
24. Unknown
Conservative impact.
25. No Silent Heuristic Authority
Inferred ownership cannot be treated as proof for strict release skipping unless policy permits.
26. Workspace Discovery
Starts from exact SourceSnapshotId.
27. Discovery Inputs
Examples:
Cargo.toml
go.mod
package.json
pyproject.toml
pom.xml
build.gradle
CMakeLists.txt
Package.swift
forgeyard.ron
28. Discovery Adapter
#![allow(unused)]
fn main() {
#[async_trait]
pub trait WorkspaceGraphAdapter {
async fn discover(
&self,
snapshot: SourceSnapshotRef,
context: GraphDiscoveryContext,
) -> Result<GraphFragment, GraphDiscoveryError>;
}
}
29. Adapter Output
Normalized graph fragment.
30. No Ecosystem-Specific Types in Core Graph
Critical.
31. Rust Adapter
Can use Cargo metadata semantics.
32. Cargo Features
Feature configuration affects graph.
33. Target-Specific Dependencies
Represent conditions.
34. Conditional Edge
#![allow(unused)]
fn main() {
pub struct ConditionalDependency {
pub edge: GraphEdge,
pub condition: GraphCondition,
}
}
35. Graph Condition
Examples:
platform
feature
profile
environment class
36. Graph Configuration
#![allow(unused)]
fn main() {
pub struct GraphConfiguration {
pub target_platforms: Vec<PlatformDescriptor>,
pub feature_sets: Vec<FeatureSetId>,
pub profiles: Vec<BuildProfileId>,
}
}
37. Multiple Configurations
Same source snapshot may produce different dependency graphs.
38. GraphConfigId
#![allow(unused)]
fn main() {
pub struct GraphConfigId(Digest);
}
39. C/C++
Static dependency discovery can be harder.
40. Sources
Potential:
CMake codemodel
compile_commands.json
declared target graph
header include scans
41. Header Dependencies
Can be dynamic/generated.
42. Conservative C/C++ Mode
Unknown header/codegen dependency expands impact broadly.
43. Java/JVM
Use Gradle/Maven project graph.
44. JavaScript/TypeScript
Workspace/package manager graph.
45. Python
Package/module boundaries can be weak.
Prefer declared project/package graph + optional import analysis.
46. Import Analysis
Optimization only.
47. Polyglot Graph
Merge fragments by explicit cross-ecosystem edges.
48. Cross-Language Edge
Example:
Rust server
depends on
generated protobuf
generated from
protocol schema
49. Schema Node
Custom/configuration file can be first-class dependency node.
50. Generated Source
Critical for correct impact.
51. Codegen Edge
generated file
--GeneratedFrom-->
schema
or target dependencies.
52. Generated Output Identity
Prefer generator target rather than committing generated files if workflow.
53. Build Script
Rust build.rs can create broad dependencies.
54. Dynamic Build Script Inputs
Hermetic system should declare.
55. Undeclared Dynamic Input
Impact analysis cannot prove safety.
56. Strict Mode
Unknown dynamic inputs => affected broadly.
57. Graph Completeness
#![allow(unused)]
fn main() {
pub enum GraphCompleteness {
Complete,
DeclaredComplete,
Partial,
Unknown,
}
}
58. Complete
Strongly modeled.
59. Partial
Some dependency classes unknown.
60. Impact Decision Must Carry Completeness
Critical.
61. Change Set
#![allow(unused)]
fn main() {
pub struct SourceChangeSet {
pub base: SourceSnapshotId,
pub head: SourceSnapshotId,
pub changes: Vec<FileChange>,
}
}
62. File Change
#![allow(unused)]
fn main() {
pub enum FileChangeKind {
Added,
Modified,
Deleted,
Renamed,
TypeChanged,
}
}
63. Rename
Retain old/new path.
64. Diff Source
VCS adapter or canonical tree diff.
65. Canonical Tree Diff
VCS-neutral.
66. Dirty Workspace
Impact can compare working SourceSnapshot to base.
67. Base Resolution
Exact snapshot.
68. No Branch String After Resolution
Critical.
69. Direct Impact
Changed file owners.
70. DirectImpactSet
#![allow(unused)]
fn main() {
pub struct DirectImpactSet {
pub changed_files: BTreeSet<RepoRelativePath>,
pub directly_affected: BTreeSet<GraphNodeId>,
pub unknown_files: BTreeSet<RepoRelativePath>,
}
}
71. Unknown File
Policy chooses broad expansion.
72. Examples
Top-level:
Cargo.lock
rust-toolchain.toml
CI config
shared schema
can affect broad graph.
73. Global Impact Pattern
Configured.
74. GlobalImpactRule
#![allow(unused)]
fn main() {
pub struct GlobalImpactRule {
pub path: PathPattern,
pub scope: ImpactScope,
}
}
75. Impact Scope
#![allow(unused)]
fn main() {
pub enum ImpactScope {
Repository,
Workspace(WorkspaceId),
Package(SourcePackageId),
Target(TargetLogicalId),
}
}
76. Lockfile Change
Usually broad within ecosystem workspace.
77. Toolchain Change
Potential repository-wide.
78. Policy File Change
May require policy/check re-evaluation broadly.
79. Pipeline Config Change
Can affect execution plan independently of source graph.
80. Architecture Rule
Pipeline/config impact evaluated separately and unioned.
81. Reverse Dependency Expansion
changed dependency
↓
all reverse dependents
82. Affected Set
#![allow(unused)]
fn main() {
pub struct AffectedSet {
pub graph: RepositoryGraphId,
pub change: SourceChangeSetId,
pub nodes: BTreeSet<GraphNodeId>,
pub reasons: BTreeMap<GraphNodeId, Vec<ImpactReason>>,
pub confidence: ImpactConfidence,
}
}
83. Impact Reason
Examples:
DirectFileChange
ReverseDependency
GlobalRule
GeneratedSource
UnknownOwnership
PolicyExpansion
ManualInclude
84. Explainability
Every affected target should be explainable.
85. forgeyard affected explain
Shows dependency chain.
86. Impact Confidence
#![allow(unused)]
fn main() {
pub enum ImpactConfidence {
ProvenConservative,
ConservativeWithUnknowns,
Heuristic,
Unknown,
}
}
87. ProvenConservative
Graph contains enough information and algorithm never excludes possible dependent.
88. Heuristic
Cannot be used for high-assurance skipping unless policy opts in.
89. Unaffected Set
Be careful.
90. Claim
Forgeyard should say:
not selected by current impact analysis
rather than absolute “unaffected” when confidence limited.
91. IncrementalPlanId
#![allow(unused)]
fn main() {
pub struct IncrementalPlanId(Digest);
}
92. Incremental Plan
#![allow(unused)]
fn main() {
pub struct IncrementalExecutionPlan {
pub id: IncrementalPlanId,
pub pipeline_plan: PipelinePlanId,
pub graph: RepositoryGraphId,
pub change: SourceChangeSetId,
pub selected_jobs: BTreeSet<JobIrId>,
pub skipped_jobs: BTreeMap<JobIrId, SkipReason>,
}
}
93. Pipeline Mapping
Jobs can declare affected target selectors.
94. Job Affected Selector
#![allow(unused)]
fn main() {
pub enum AffectedSelector {
Repository,
Workspace(WorkspaceSelector),
Targets(Vec<TargetSelector>),
Tests(TestSelector),
Artifacts(ArtifactSelector),
}
}
95. Example Pipeline
Conceptually:
job: (
name: "rust-tests",
affected: Targets(["//crates/..."]),
)
96. Do Not Make Human Config Overly Complex
Adapters can infer common selectors.
97. Job Selection
If affected set intersects selector, run.
98. Required Jobs
Policy can force run regardless impact.
99. Job Classification
#![allow(unused)]
fn main() {
pub enum IncrementalJobMode {
Always,
AffectedOnly,
AffectedOrPolicy,
Manual,
}
}
100. Always
Security/release/global checks.
101. AffectedOnly
Safe optimization where permitted.
102. AffectedOrPolicy
Default flexible.
103. Manual
Explicit.
104. Policy Expansion
Policy can union additional jobs.
105. Example
Change Proposal:
affected unit tests
+
always lint/security
Stable release:
all Tier-1 test suites
106. No Policy Contraction by Impact Engine
Critical.
Impact engine proposes minimum/selected set; policy may expand.
107. Required Work Set
FinalWorkSet =
AffectedWork
∪ AlwaysRun
∪ PolicyRequired
∪ UserExplicit
108. Never Subtract PolicyRequired
Critical.
109. Test Impact
Part 32 integration.
110. Direct Test Mapping
Tests belong to target/package.
111. Coverage-Based Test Impact
Future optional.
112. Historical Test Correlation
Optional heuristic.
113. Baseline Safe Test Selection
all tests for affected targets
114. More Aggressive Selection
Can use:
test-to-file coverage map
dependency graph
historical mapping
but confidence lower.
115. Mandatory Test Floor
Policy.
116. No Opaque AI-Only Selection
Critical.
117. Benchmark Impact
Part 33 integration.
118. Performance Benchmarks
Run only for affected relevant targets in PR, broader on release/nightly.
119. Artifact Impact
Build artifact target graph.
120. Release Impact
Can answer:
which packages/releases potentially changed?
121. But Release Completeness
Stable release may rebuild/repackage all required targets from same source according to policy.
122. Cache Integration
Impact and cache are distinct.
123. Affected But Cache Hit
Job selected, then cache may satisfy without execution.
124. Unaffected But Cache Miss
If policy allows affected-only, job may remain skipped.
125. Correct Order
impact/policy selects logical work
↓
cache checks selected work
↓
execute misses
126. Do Not Use Cache to Decide Semantic Impact
Critical.
127. Derivation Integration
Hermetic derivations already encode inputs.
128. Fine-Grained Incremental Build
Can use derivation dependencies where ecosystem adapter maps them.
129. Source Digest Inputs
Target derivation can hash relevant source subset.
130. Avoid Entire Repo Hash
Where safe.
131. TargetInputSet
#![allow(unused)]
fn main() {
pub struct TargetInputSet {
pub target: TargetLogicalId,
pub files: BTreeSet<RepoRelativePath>,
pub dependencies: BTreeSet<TargetLogicalId>,
pub config_inputs: BTreeSet<RepoRelativePath>,
}
}
132. Input Set Completeness
Versioned/confidence.
133. Hermetic Advantage
Declared inputs improve impact precision.
134. Dynamic Inputs
Reduce confidence.
135. CAS Graph Storage
Repository graph snapshot can be canonical serialized into CAS.
136. Metadata
Graph ID/source/config/completeness stored in DB.
137. Graph Size
Large monorepos can have millions of nodes/edges.
138. In-Memory Representation
Use compact indexes/arenas.
139. Serialization
Postcard suitable internally.
140. Query Indexes
Maintain:
node by logical ID
file -> owners
node -> deps
node -> reverse deps
package -> targets
target -> tests
141. BTree vs Hash
Deterministic serialization uses ordered structures.
Runtime indexes can use hash maps.
142. Graph Construction Parallelism
Rayon appropriate for CPU-heavy parsing/merging.
143. Tokio
I/O/discovery orchestration.
144. Incremental Graph Rebuild
Future optimization.
145. Baseline
Rebuild graph per source snapshot or cache by manifest/input digests.
146. Graph Fragment Cache
Adapter fragment cache.
147. Fragment Cache Key
adapter version
manifest digests
relevant config
toolchain metadata
148. Graph Cache Is Derived
Can discard/rebuild.
149. Graph Snapshot Reuse
If same SourceSnapshotId + GraphConfigId + adapter versions, reuse exact graph.
150. Graph Diff
#![allow(unused)]
fn main() {
pub struct GraphDiff {
pub base: RepositoryGraphId,
pub head: RepositoryGraphId,
pub added_nodes: Vec<GraphNodeId>,
pub removed_nodes: Vec<GraphNodeId>,
pub changed_edges: Vec<GraphEdgeChange>,
}
}
151. Graph Structural Change
Can itself expand affected scope.
152. Example
Dependency added:
A now depends on B
A affected even if A source file unchanged.
153. Manifest Change
Directly affects package/target graph.
154. Deleted Target
Downstream pipeline jobs may become invalid.
155. Plan Validation
Incremental planner checks selected job references still exist.
156. Cycles
Some dependency graphs contain cycles.
157. Strongly Connected Components
Collapse SCCs.
158. Impact
If one node in SCC changes, all SCC members affected.
159. Build Scheduling
Underlying build system may handle cycles or reject.
160. Forgeyard Graph
Must represent without infinite traversal.
161. GraphCycleId
Optional.
162. Cycle Diagnostic
Show path.
163. Invalid Cycle
Adapter may mark error.
164. Ownership Overlap
One file can affect multiple targets.
165. Shared Config File
Expected.
166. Glob Ownership
Declared patterns.
167. Glob Changes
If ownership rules change, graph rebuild.
168. Ignore Rules
VCS ignore does not automatically mean impact-ignore.
169. Forgeyard Ignore
Separate config for non-impact files:
docs-only
examples
generated outputs
170. Ignore Safety
Strict policy.
171. Docs Change
May still affect docs site/package.
172. No Broad .md Ignore by Default
Critical.
173. Manual Include
Pipeline/user can force targets.
174. Manual Exclude
High risk.
175. Recommendation
Do not allow user arbitrary exclusion from required policy jobs.
176. Impact Override
If permitted:
#![allow(unused)]
fn main() {
pub struct ImpactOverride {
pub scope: ResourceScope,
pub include: BTreeSet<TargetLogicalId>,
pub exclude: BTreeSet<TargetLogicalId>,
pub reason: BoundedString,
}
}
177. Exclude Permission
High privilege.
178. Audit
Mandatory.
179. Release
Exclusion probably forbidden by default.
180. Monorepo Ownership
Can answer:
who owns affected components?
181. Ownership Source
Change Proposal ownership/CODEOWNERS-like system.
182. Component Owner
Not authorization itself.
183. Review Routing
Can inform required reviewers.
184. Policy
May require owners for affected components.
185. Component Boundary
#![allow(unused)]
fn main() {
pub struct ComponentId(Digest);
}
Higher-level grouping across packages/targets.
186. Component
Examples:
scheduler
runner
web UI
Android app
187. Component Graph
Derived view.
188. Architectural Boundary
Can integrate architecture.ron.
189. Dependency Rule
Forbidden edges can be checked.
190. Architecture Lint
Part of affected validation.
191. If changed component adds forbidden dependency
Fail architecture check.
192. Search Integration
Part 31 indexes:
target
package
component
dependencies
owners
193. Graph Query API
Examples:
deps(target)
rdeps(target)
owners(file)
affected(base, head)
path(A, B)
194. Query Language
Typed, bounded.
195. No Arbitrary Graph Program
Baseline.
196. CLI
forgeyard graph build
forgeyard graph show
forgeyard graph deps <target>
forgeyard graph rdeps <target>
forgeyard graph path <a> <b>
forgeyard affected --base <ref>
forgeyard affected explain <target>
forgeyard affected jobs
197. graph show
Summary.
198. graph deps
Direct/transitive option.
199. Depth Limit
Bounded.
200. affected
Shows:
changed files
direct targets
reverse dependents
selected jobs
policy expansions
confidence
201. Dioxus UI
Pages:
Repository Graph
Components
Affected Changes
Dependency Explorer
Impact Explanation
202. Change Proposal UI
Affected components panel.
203. Pipeline Plan UI
Show:
selected
skipped due to unaffected
forced by policy
cache-hit
204. Skip Transparency
Critical.
205. User Must Know Why Job Did Not Run
206. SkipReason
#![allow(unused)]
fn main() {
pub enum SkipReason {
NotAffected,
PolicyNotRequired,
ReplacedByEquivalentEvidence,
UserExcludedAuthorized,
}
}
207. Cache Hit Is Not SkipReason
It’s execution result path.
208. Job State
Can use existing Skipped semantics with structured reason.
209. Incremental Evidence
Store selected/skipped reasoning.
210. IncrementalPlanningEvidenceId
#![allow(unused)]
fn main() {
pub struct IncrementalPlanningEvidenceId(Digest);
}
211. Change Proposal Check
Can publish:
Affected: 12/248 targets
Required jobs: 18
Skipped: 43
212. No Marketing “100x Faster” Claims Without Evidence
213. Analytics
Track:
jobs skipped
compute saved
cache hits
impact expansion ratio
false-negative incidents
214. False Negative
Important.
215. Definition
Impact analysis skipped work that later proves affected.
216. Detection
Can use periodic full-validation comparison.
217. Shadow Validation
Run full suite periodically and compare affected plan.
218. Impact Confidence Calibration
Excellent production mechanism.
219. Nightly Full Validation
Recommended.
220. Release Full Validation
Recommended for critical projects.
221. False-Negative Record
#![allow(unused)]
fn main() {
pub struct ImpactMiss {
pub graph: RepositoryGraphId,
pub change: SourceChangeSetId,
pub skipped_target: TargetLogicalId,
pub evidence: ImpactMissEvidence,
}
}
222. Impact Miss
Triggers:
warning
adapter correction
confidence downgrade
223. No Silent Miss Suppression
Critical.
224. Graph Adapter Quality Metrics
completeness
unknown ownership rate
impact miss rate
225. Health
Checks:
graph build success
projection lag
unknown-file ratio
adapter errors
impact miss rate
226. Doctor
forgeyard graph doctor
227. Doctor Checks
workspace manifests
adapter availability
graph completeness
cycles
orphan files
unknown ownership
global rules
228. Orphan File
Tracked source file with no owner.
229. Orphan Policy
Can warn/fail depending repo.
230. Config
(
graph: (
global_impact: [
"Cargo.lock",
"rust-toolchain.toml",
".forgeyard/**",
],
),
)
231. Path Pattern Engine
Bounded, deterministic.
232. No Arbitrary Regex Needed
Globs sufficient baseline.
233. Security
Manifest parsers untrusted.
234. External Build Tool Invocation
If adapter invokes:
cargo metadata
gradle
bazel query
run sandboxed/bounded.
235. Network
Discovery defaults network denied where possible.
236. Generated Config
Do not execute arbitrary project code in daemon.
237. Discovery Worker
Can run as sandboxed job for risky ecosystems.
238. Daemon Never Executes Arbitrary Build Scripts Directly
Existing invariant.
239. Graph Adapter Trust
Built-in first-party adapters preferred.
240. Plugin Graph Adapter
Possible trusted external, not sandboxed result accepted blindly.
241. Host Validates Graph Bounds
242. Graph Bomb
Malicious repo could generate enormous graph.
243. Limits
max nodes
max edges
max path length
max manifest count
244. Quotas
Part 27 resource governance.
245. Tenant Isolation
Graphs belong to tenant/project.
246. Cross-Tenant Graph
Forbidden.
247. Public OSS Mirror
Still own tenant/project graph.
248. Graph Data Sensitivity
Package/target names may reveal proprietary architecture.
249. Authz
Graph read permission.
250. Permissions
graph.read
graph.build
impact.read
impact.override
251. API
Potential:
GET /v1/projects/{id}/graph
GET /v1/projects/{id}/graph/dependencies
GET /v1/projects/{id}/affected
GET /v1/runs/{id}/incremental-plan
POST /v1/projects/{id}/graph/rebuild
252. Large Graph Response
Paginated/streamed/subgraph only.
253. Graph Export
RON/Postcard internal; JSON external.
254. Graph Visualization
UI fetches bounded subgraph.
255. No Entire Million-Node Graph to Browser
Critical.
256. Graph Rebuild
Async.
257. Rebuild Result
New RepositoryGraphId.
258. Graph Cache
Derived; backup optional.
259. DR
Rebuild from SourceSnapshot and config.
260. Source Retention
Graph reproduction requires source snapshot retained.
261. Historical Incremental Plan
Store graph/evidence IDs.
262. Missing Old Graph
Can still inspect stored IncrementalPlanningEvidence.
263. Supply Chain
Could include graph/impact evidence in change checks, not release provenance baseline unless desired.
264. RBE
Bazel already has fine-grained action graph.
265. RBE Integration
Do not duplicate Bazel internals blindly.
266. REAPI Action Graph
Can use RBE action-level caching independently.
267. Forgeyard Monorepo Graph
Higher-level workspace/pipeline planning.
268. Bazel Adapter
Can import target graph via query/cquery semantics if supported.
269. Cache
Bazel action cache remains lower level.
270. Scheduler
Selected jobs only become scheduler jobs.
271. Fairness
Unchanged.
272. Change Proposal
Exact base/head snapshots.
273. Merge Queue
Target branch may advance.
274. Integration Candidate
Recompute affected set against exact integration candidate/base as needed.
275. Critical
Affected analysis based on old base may be stale after queue rebase.
276. Merge Queue Rule
Re-plan/re-evaluate when target revision changes.
277. IncrementalPlan Freshness
#![allow(unused)]
fn main() {
pub enum IncrementalPlanFreshness {
Current,
StaleBase,
StaleGraph,
StalePolicy,
}
}
278. Stale Plan
Cannot authorize final merge if policy requires current.
279. Release Candidate
Usually full required validation.
280. Nightly
Good place for broad/full tests to validate impact system.
281. Local Developer Mode
Affected analysis useful:
forgeyard run --affected
282. Standalone
Graph stored locally.
283. Distributed
Shared graph metadata/CAS.
284. Local Uncommitted Changes
Canonical working-tree snapshot.
285. Base
User selects/ref resolved exactly.
286. Developer Explain
Show why local command runs target.
287. Incremental Build UX
Potential:
3 files changed
7 targets affected
12 jobs required
8 cache hits
4 executed
288. Observability Metrics
graph_build_duration_seconds
graph_nodes
graph_edges
graph_unknown_files
impact_targets_selected
impact_jobs_skipped
impact_policy_expansions
impact_misses_total
graph_rebuild_failures_total
289. Labels
Low cardinality:
ecosystem
result
confidence
290. No Target IDs in metrics
Use analytics/search.
291. Tracing
graph.discover
graph.merge
graph.query
impact.compute
incremental.plan
graph.reconcile
292. Event
RepositoryGraphBuilt
RepositoryGraphFailed
ImpactComputed
ImpactMissDetected
293. Audit
Audit only:
impact override
graph admin config change
not every normal graph computation.
294. Notifications
Potential:
impact system degraded
high impact miss rate
required full validation
295. Search/Analytics
Part 31.
296. Testkit
forgeyard-graph-testkit/src/
├── lib.rs
├── graph.rs
├── fragment.rs
├── diff.rs
├── impact.rs
├── cycles.rs
├── policy.rs
└── assertions.rs
297. Unit Tests
Graph traversal.
298. Reverse Dependency Test
Direct change expands correctly.
299. Cycle Test
SCC handled.
300. Unknown File Test
Conservative expansion.
301. Lockfile Test
Workspace-wide impact.
302. Toolchain Test
Configured global impact.
303. Generated Source Test
Schema change affects generated consumers.
304. Graph Structural Change Test
Manifest edge change affects dependent target.
305. Base Change Test
Stale incremental plan rejected.
306. Merge Queue Test
Target-base update triggers recomputation.
307. Policy Expansion Test
Policy-required job never removed.
308. Cache Order Test
Impact selects before cache resolution.
309. Test Impact Test
Affected target selects associated tests.
310. Release Full Validation Test
Policy expands beyond PR impact.
311. Heuristic Test
Heuristic confidence cannot satisfy strict skip policy.
312. Impact Explain Test
Every selected target has reason chain.
313. Orphan File Test
Reported.
314. Path Rename Test
Correct old/new ownership.
315. Deleted Package Test
Graph/planner handles.
316. Polyglot Test
Cross-language edge propagates.
317. Graph Bomb Test
Limits enforced.
318. Tenant Isolation Test
No cross-tenant graph access.
319. DR Test
Graph rebuilt from retained source.
320. Shadow Validation Test
Detect skipped target miss.
321. Fuzzing
Fuzz graph serializers, path/glob parser, query parser.
322. Property Tests
Transitive affected closure contains all reverse dependents of direct impacted nodes.
323. Scale Tests
Millions of nodes/edges.
324. Large Monorepo Test
Measure:
discovery
graph build
affected query
reverse traversal
325. Implementation Phase 1 — Core Graph Model
Nodes/edges/config/completeness.
326. Phase 2 — Rust/Cargo Adapter
First-class dogfood.
327. Phase 3 — Source Diff & Direct Impact
File ownership.
328. Phase 4 — Reverse Dependency Impact
Affected targets.
329. Phase 5 — Pipeline Incremental Planning
Selected/skipped jobs.
330. Phase 6 — Policy Expansion
Strict correctness.
331. Phase 7 — Test/Benchmark Integration
Affected quality work.
332. Phase 8 — Polyglot Adapters
Go/JS/Python/JVM/C++ etc.
333. Phase 9 — UI/CLI/Search
Developer experience.
334. Phase 10 — Shadow Validation/Impact Miss Intelligence
Trust calibration.
335. Phase 11 — Large-Monorepo Optimization
Fragment cache/parallelism.
336. Phase 12 — Scale/Fuzz/DR Hardening
Production readiness.
337. Acceptance Tests
- Every graph binds exact SourceSnapshotId.
- Graph configuration/version is part of identity.
- Ecosystem-specific types do not leak into core graph model.
- File ownership confidence is explicit.
- Unknown ownership causes conservative handling.
- Global-impact files are configurable and explainable.
- Dependency edges have explicit semantics.
- Reverse-dependency traversal drives affected expansion.
- Generated-source relationships propagate impact.
- Graph structural changes can affect targets even without source-file edits.
- Cycles are handled via SCCs without infinite traversal.
- Affected target reason chains are explainable.
- Impact confidence is explicit.
- Heuristic impact cannot silently satisfy strict release skipping.
- Final work set always includes policy-required jobs.
- Impact engine never subtracts policy-required work.
- Impact selection occurs before cache resolution.
- Cache hits do not define semantic impact.
- Test selection has a policy-defined mandatory floor.
- Benchmark selection can be narrower for PR and broader for release.
- Merge-queue base changes invalidate/recompute affected plans.
- Stale graph/base/policy marks IncrementalPlan stale.
- Incremental skip reasons are persisted and visible.
- Users can explain why a job ran or skipped.
- Impact overrides are scoped/audited.
- Daemon never executes arbitrary project build scripts directly for discovery.
- Malicious repositories cannot create unbounded graph structures.
- Tenant graph data is isolated.
- Search/analytics are derived from graph state.
- Graph can rebuild after DR.
- Shadow/full validation can detect impact misses.
- Impact misses reduce trust/confidence rather than being hidden.
- Standalone/distributed share graph semantics.
- Polyglot cross-language dependencies can be represented.
- Forgeyard dogfoods monorepo impact analysis on its own Rust workspace.
338. Production Readiness Gates
Do not call monorepo incremental execution production-ready until:
exact graph identity is stable
Rust workspace graph is accurate
unknown ownership is conservative
global-impact rules are explicit
reverse-dependency closure is tested
policy expansion cannot be bypassed
stale base/graph/policy invalidates plans
impact explanations are persisted
shadow/full validation measures misses
large-repository limits and fuzz tests pass
339. Architectural Invariants
- repository graph is derived state;
- source snapshot is immutable/exact;
- graph identity includes config/schema/adapter semantics;
- impact analysis is optimization, not unconditional correctness authority;
- unknown dependency means conservative expansion;
- ownership confidence is explicit;
- heuristic results cannot masquerade as proof;
- policy can always expand required work;
- impact engine never removes policy-required work;
- selected work is determined before cache lookup;
- cache does not define semantic impact;
- generated-source relationships are explicit;
- structural graph changes are first-class;
- cycles cannot break traversal;
- skip reasons are durable/explainable;
- stale base/graph/policy invalidates incremental plan;
- merge-queue target movement triggers recomputation;
- test selection retains mandatory policy floor;
- release validation can be broader than PR validation;
- impact overrides are privileged/audited;
- discovery never gives arbitrary repository code daemon authority;
- graph input/output size is bounded;
- tenant graphs are isolated;
- graph can be rebuilt from source/config;
- shadow validation detects false-negative impact;
- misses are recorded, not hidden;
- polyglot graphs share one normalized model;
- standalone/distributed share semantics;
- graph/search/analytics never become authz authority;
- Forgeyard dogfoods affected-change planning on its own monorepo.
340. Final Target Architecture
SourceSnapshotId
│
▼
Graph Discovery
│
▼
Repository Graph
│
┌────────────┼────────────┐
▼ ▼ ▼
Files Targets Tests
│ │ │
└────────────┼────────────┘
▼
Source Diff
│
▼
Impact Closure
│
┌────────────┼────────────┐
▼ ▼ ▼
Affected AlwaysRun PolicyRequired
│ │ │
└────────────┼────────────┘
▼
Final Work Set
│
▼
Cache Check
│
▼
Execute
341. Final Architectural Position
Impact analysis:
exact base snapshot
+
exact head snapshot
+
versioned repository graph
+
changed files
↓
direct ownership
↓
reverse dependency closure
↓
confidence + reasons
Incremental planning:
AffectedWork
∪ AlwaysRun
∪ PolicyRequired
∪ ExplicitIncludes
↓
selected logical jobs
↓
cache resolution
↓
execution
Safety calibration:
incremental PR validation
↓
periodic/full validation
↓
compare results
↓
detect ImpactMiss
↓
fix adapter/rules
↓
adjust confidence
The key guarantee is:
Forgeyard can scale efficiently to large monorepos without converting change-impact heuristics into hidden correctness assumptions. Every skipped job is explainable, policy can always require broader validation, unknown dependencies expand conservatively, and periodic full validation measures whether the optimization remains trustworthy.
342. Extended Architecture Sequence
01 Core Domain & Foundation
02 Storage & Metadata
03 CAS & Artifact Data Plane
04 Pipeline IR / Parsing / Planning
05 Run / Job State Machine
06 Scheduler
07 Runner / Agent
08 Sandbox & Executor
09 Transport / QUIC / Protocol
10 Events / Reconciliation
11 Policy / Authorization / Identity
12 Secrets & Trust
13 Supply Chain / SBOM / Provenance / Signing
14 Packaging
15 Release
16 Deployment
17 Observability / Health / Doctor
18 API / Axum
19 Dioxus UI
20 Device Lab
21 SCM Provider Integrations
22 HA / Coordination / Raft
23 RBE Interop
24 Plugin / Extension Architecture
25 Operations / Backup / Upgrade / DR
26 Self-Hosting / Bootstrap / Release of Forgeyard
27 Multi-Tenancy / Quotas / Resource Governance
28 Audit / Compliance / Evidence Retention / Security Governance
29 Notifications / Alerting / Human Workflow
30 Entitlements / Licensing / Subscription / Commercial Access Control
31 Search / Indexing / Query / Operational Analytics
32 Test Results / Quality Gates / Coverage / Flaky-Test Intelligence
33 Benchmarking / Performance Regression / Load-Test / Capacity Intelligence
34 Monorepo Intelligence / Dependency Graph / Affected-Change / Incremental Execution