ai.seo.md, docs/CURRENT-STATUS.md, docs/README.md, docs/PUBLIC-API.md,
llms.txt, llms-full.md, docs-site/llms.txt, docs-site/llms-full.md,
and 21 docs-site/**/index.html page footers) still described the .NET line
as 2.0.1 and/or the Java line as 2.2.0, even though 2.2.0 already
aligned the two ecosystems onto a single shared version number. The
docs-site install snippet (dotnet add package Foundgine.Runtime/Providers
--version 2.0.1) and the homepage hero badge (v2.0.1) had the same
problem. All now read 2.2.1 consistently..github/workflows/java-build.yml’s java-security-penetration job,
which called mvn -pl security/pentest -am verify — security/pentest
has never been a Maven module (it’s the live-scanner script directory, no
pom.xml), so the job failed outright. It now runs
security/pentest/run-all.sh with SKIP_LIVE=true.run-all.sh itself, plus a second,
previously-latent one: ROOT only climbed one directory from
security/pentest, landing in security/ (no pom.xml) instead of
src/java, which also broke the script’s live-check paths
(run-nmap.sh/run-zap.sh) whenever SKIP_LIVE was unset.publish-nuget (build.yml) previously did not wait on
supplychain-sample-tests, supplychain-semantic-sample-tests, or any
security.yml job before publishing to NuGet — the latter was structurally
impossible, since needs: cannot reference a job in a different top-level
workflow. security.yml now also triggers via workflow_call (its
schedule/workflow_dispatch triggers are unchanged), build.yml calls it
through a new security-gate job, and publish-nuget now depends on all of
the above plus security-gate.publish-maven (java-build.yml) previously did not wait on
java-security-penetration before publishing to Maven Central. It now does.2.2.1.NET 9 / Java 21docs/SECURITY.md (“the semantic API’s
response verbosity”): SupplyChainMcpTools.PolicyProbe (the sample
policy_probe MCP tool under src/csharp/samples/Foundgine.SupplyChain.Advanced/Semantic/Api/Mcp)
now only returns its full kind/predicate/named-claim decision detail
when the host is running in a development environment
(IHostEnvironment.IsDevelopment()). In every other environment it logs
the full decision server-side via ILogger, keyed by a short opaque
correlation id, and returns only { allowed: false, reference: <id> } —
matching the correlation-id pattern MCP.Foundgine/Program.cs’s Execute
helper already used for the execution API, so a caller probing many
attack variants can no longer use the response shape to map policy
boundaries.Foundgine.Core/foundgine-core,
Foundgine.Runtime/foundgine-runtime,
Foundgine.Providers/foundgine-providers, and
Foundgine.Extensions/foundgine-extensions.MIT to
Apache-2.0. The packaged LICENSE file was always the Apache License,
2.0 text; only the PackageLicenseExpression in Directory.Build.props
disagreed with it. Added an equivalent <licenses> declaration to the
Java src/java/pom.xml parent so both ecosystems advertise the same
license.2.0.0-SNAPSHOT as a literal string
in ten separate pom.xml files (the parent’s own <version>, every
module’s <parent> reference, and most intra-repo <dependency>
versions), even though a <revision> property already existed and was
already used correctly in a few places (e.g. the sample projects’
annotation-processor path). That property was otherwise dead — nothing
read it. src/java/pom.xml now sets <version>${revision}</version> on
the parent itself, every module and intra-repo dependency below it
references ${revision}, and flatten-maven-plugin resolves that
property into a concrete version in any installed/deployed POM. This
makes revision the single source of truth for the Java release version,
the equivalent of VersionPrefix in ../../Directory.Build.props for
the C# tree.<description> elements to the foundgine-runtime and
foundgine-providers POMs (mirroring Foundgine.Runtime and
Foundgine.Providers on the C# side); foundgine-core and
foundgine-extensions already had one.2.2.0.NET 9 / Java 21Foundgine.SupplyChain.Advanced.Mcp.Api under src/csharp/samples/Foundgine.SupplyChain.Advanced/Semantic/Api/Mcp) exposing describe_capabilities, read_entity, read_relationship, write_entity, and policy_probe tools directly against the sample’s composed semantic model. This is additive: it runs standalone and is not wired into the Supply Chain E2E harness.src/csharp/samples/Foundgine.SupplyChain.Advanced/MCP.Foundgine (the Postgres-backed MCP server the Supply Chain E2E Agent and run-supply-chain.ps1 actually depend on — get_order, get_inventory, list_suppliers, and the rest of the Agent’s tool contract) along with its docker-compose.yml service and solution entries, without updating the harness. This broke run-supply-chain.ps1 at step 3/8 with no such service: mcp-foundgine. Restored the MCP.Foundgine project, its docker-compose.yml service, and its Foundgine.sln entries so the Supply Chain E2E + PenTest harness runs again.src/csharp/benchmarks/AgentEndToEnd/Run5/docker-compose.yml that had stripped its mcp-foundgine service block while the project files were left in place, which would have broken Run5 the same way.2.1.0.NET 9CandidateTruncation diagnostics to SemanticLexicalResolver: when a token’s retrieved candidate set exceeds candidateLimit, the resolver now records how many candidates were kept vs. discarded, the retrieval score at each side of the cut, and the resulting MarginGap. Candidates cut at retrieval time never reach graph search, so previously they were simply gone with no record of whether one might have represented a distinct, legal meaning.GroundingDecision gains TruncationRisks (empty, never null, via EffectiveTruncationRisks). When the leading interpretation depends on a token whose highest-scoring truncated candidate falls within the resolver’s ambiguity margin of the lowest candidate it kept, the outcome is now RequiresClarification instead of Committed — the same “don’t silently pick a winner inside the margin” policy that already governs surviving interpretations, applied one stage earlier to a candidate that never got the chance to survive or fail on its merits.Committed outcome into RequiresClarification, but never the reverse, and it does not change grounding for expressions with no truncation.SemanticLexicalResolverTests coverage for the new truncation-risk path: within-margin truncation forcing clarification, clear-margin truncation still committing, and the diagnostic being empty when no truncation occurs.2.0.3.NET 9SemanticLexicalResolver.Ground so the compact-name fallback (e.g. customer profile → customerprofile, purchase order → purchaseorder) is actually reached: the initial per-token retrieval pass now stops as soon as any single token comes back with no candidates, instead of continuing to query the remaining tokens first. Continuing to query every token before falling back was spending the shared retrieval-timeout budget on results that were about to be discarded anyway, which could starve the compact-fallback lookup of the time it needed and made it appear as though the fallback simply hadn’t run.KeyNotFoundException in the “no lexical candidate” diagnostic: if the compact-name fallback itself also returned no candidates, the resolver could try to look up a token that had never been queried (because retrieval stopped early per the fix above) and crash instead of reporting GroundingOutcome.Unresolved cleanly.Ground_uses_one_retrieval_deadline_across_compact_token_fallback (both Foundgine.Semantics.Tests and the Foundgine.SupplyChain.Advanced sample) so the assertions no longer depend on sub-15ms real-time scheduling precision. Windows’ default thread-timer resolution can silently round a Thread.Sleep(1) up to ~15ms, which was enough on its own to exhaust the previous 10ms retrieval budget before the compact-token lookup even started. The test now uses a TimeSpan.Zero sleep for the always-fast lookup and a 200ms budget with a 500ms fallback delay, comfortably clear of any plausible scheduler jitter, while asserting exactly the same behavior.2.0.2.NET 9candidateLimit documentation to describe the implemented total per-token limit across semantic kinds.GroundingInterpretation.Confidence to InterpretationScore to make its heuristic ranking semantics explicit.Weight is application-declared evidence weight, not confidence or priority.CompetingInterpretations is internal semantic metadata and should be projected safely before exposure to untrusted callers.Corrected the advanced Supply Chain weighted-alias test so it asserts only the semantic identity that actually participated in lexical grounding.
purchase order when token-by-token lexical retrieval does not produce a candidate.purchase orders / buys → PurchaseOrdersupplier / seller → SupplierAliasWeightEvidenceGate for thresholded, fail-closed evidence evaluation that never grants authorization.docs/assets/.2.0.1.NET 9License: MIT