Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion docs/getting-started/asibackbone-6-api-boundary.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ The names most often used by Learning material are:
| Durable audit ledger | `AsiBackbone.Core.Audit.IGovernanceAuditLedgerStore` |
| Actor context | `AsiBackbone.Core.Actors.GovernanceActorContext` |
| ASP.NET Core endpoint service | `AsiBackbone.AspNetCore.Endpoints.IEndpointGovernanceService` |
| ASP.NET Core policy marker attribute | `AsiBackbone.AspNetCore.Endpoints.GovernancePolicyAttribute` |
| Acknowledgment challenge service | `AsiBackbone.AspNetCore.Handshakes.IAcknowledgmentChallengeService` |

These are implementation types. A Learning snippet that defines its own decision, receipt, context, or acknowledgment record is a teaching model unless the section explicitly says otherwise.
Expand Down Expand Up @@ -107,6 +108,8 @@ app.MapPost("/exports", HandleExport)

The marker records policy metadata. It does not, by itself, resolve a policy, select constraints, or enforce execution. See the exact [`EndpointGovernanceRouteBuilderExtensions`](https://github.com/AsiBackbone/AsiBackbone/blob/release/6.0.0/src/AsiBackbone.AspNetCore/Endpoints/EndpointGovernanceRouteBuilderExtensions.cs) behavior.

For attribute-based endpoint metadata, the 5.x `RequireGovernancePolicyAttribute` type was renamed to `GovernancePolicyAttribute` in 6.0.

## Removed Compatibility Surface

The upstream obsolete-member inventory found exactly seven public members whose compatibility window ended at 6.0:
Expand All @@ -121,7 +124,7 @@ The upstream obsolete-member inventory found exactly seven public members whose
| `RequireGovernancePolicy<TPolicy>(RouteHandlerBuilder)` | `MarkGovernancePolicy<TPolicy>()`, or `MarkGovernancePolicy(typeof(TPolicy))` for a plain marker |
| `RequireGovernancePolicy<TBuilder>(TBuilder, Type)` | `MarkGovernancePolicy(builder, policyType)` |

The non-obsolete `RequireGovernancePolicyAttribute` remains part of the implementation. Historical 4.x and 5.x migration material may retain old names when it is clearly presented as history; current examples must not present the removed members as callable 6.0 APIs.
The 5.x `RequireGovernancePolicyAttribute` type was renamed to `GovernancePolicyAttribute` in 6.0. That is a public type rename, not one of the seven obsolete-member removals above. Historical 4.x and 5.x migration material may retain old names when it is clearly presented as history; current examples must not present old names or removed members as 6.0 APIs.

## Decision Receipt Is Not Execution Proof

Expand All @@ -136,6 +139,7 @@ Before publishing an API-facing Learning change:
- label teaching code as illustrative or Learning-owned;
- label exact framework syntax as AsiBackbone 6.0 API;
- use finalized 6.0 names and namespaces;
- use `GovernancePolicyAttribute`, not the 5.x `RequireGovernancePolicyAttribute`, for attribute-based endpoint metadata;
- do not call removed evaluator constructors or route-builder methods;
- link implementation source to `release/6.0.0`, not `main` or a 5.x branch;
- pin any future `AsiBackbone.*` sample package reference to a released 6.x version and commit its lock-file update;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ Examples include:
| `IAsiBackboneAuditSink` | `IDecisionReceiptSink` |
| `IAsiBackboneEndpointGovernanceService` | `IEndpointGovernanceService` |
| `IAsiBackboneAcknowledgmentChallengeService` | `IAcknowledgmentChallengeService` |
| `RequireGovernancePolicyAttribute` | `GovernancePolicyAttribute` |

This is a representative teaching-oriented subset, not the complete rename inventory. Use the authoritative [6.0 public API naming convention](https://github.com/AsiBackbone/AsiBackbone/blob/release/6.0.0/docs/articles/public-api-naming-600.md) for the full list.

Expand Down Expand Up @@ -111,7 +112,7 @@ AsiBackbone 6.0 removes exactly seven public members whose obsolete compatibilit
- the five partial `DefaultAsiBackbonePolicyEvaluator<TContext>` constructors are gone; use `DefaultGovernancePolicyEvaluator.CreateBuilder<TContext>()` or the supported full-dependency constructor;
- the two `RequireGovernancePolicy(...)` route-builder extension methods are gone; use `MarkGovernancePolicy(...)` instead.

The non-obsolete `RequireGovernancePolicyAttribute` remains supported.
The 5.x `RequireGovernancePolicyAttribute` type was also renamed to `GovernancePolicyAttribute` in 6.0 so the attribute and route-builder paths use the same marker terminology. That type rename is separate from the seven obsolete-member removals.

Do not use this page as the complete implementation migration checklist. The authoritative [Upgrade from 5.x to 6.0](https://github.com/AsiBackbone/AsiBackbone/blob/release/6.0.0/docs/articles/upgrade-500-to-600.md) guide contains the exact removed-member inventory, replacement guidance, dependency-injection notes, and complete public type rename table.

Expand Down Expand Up @@ -162,7 +163,7 @@ Older content is useful when read in version context.
| --- | --- |
| `AuditResidue` or **audit residue** in an older package example | Historical 5.x naming for what current Learning and the 6.0 API call a decision receipt. Preserve the old wording when discussing the historical release itself. |
| `IAsiBackbone*`, `DefaultAsiBackbonePolicyEvaluator`, or other product-prefixed public types | Treat them as 5.x API names and translate them through the 6.0 naming and migration guides before copying code. |
| `RequireGovernancePolicy(...)` on a route builder | Treat it as historical 5.x syntax. Current 6.0 route metadata uses `MarkGovernancePolicy(...)`. |
| `RequireGovernancePolicy(...)` on a route builder or `RequireGovernancePolicyAttribute` on an endpoint | Treat them as historical 5.x names. Current 6.0 route metadata uses `MarkGovernancePolicy(...)`, and attribute-based metadata uses `GovernancePolicyAttribute`. |
| A Learning sample that declares its own context, decision, receipt, acknowledgment, capability, or gateway type | Treat it as a teaching model unless the page explicitly labels the snippet as AsiBackbone 6.0 API. |
| A historical release note, tag, or archived page | Read it as evidence of what that release taught or implemented at the time, not as the current production API contract. |
| A conceptual statement about decision-before-execution, acknowledgment, scoped authority, or host-owned execution | Treat the concept as current unless a newer Learning page explicitly revises it. Verify package-specific behavior in AsiBackbone 6.0. |
Expand Down Expand Up @@ -192,6 +193,7 @@ If you are moving a code example or internal document from an AsiBackbone 5.x ba
- [ ] Replace 5.x package type names with the finalized 6.0 names where the snippet uses the real product API.
- [ ] Replace removed partial evaluator constructors with the builder or full-dependency constructor.
- [ ] Replace removed route-builder `RequireGovernancePolicy(...)` calls with `MarkGovernancePolicy(...)`.
- [ ] Replace 5.x `RequireGovernancePolicyAttribute` usage with `GovernancePolicyAttribute`.
- [ ] Use **decision receipt** in current teaching prose while preserving historical wording in historical release material.
- [ ] Use **acknowledgment** as the ordinary teaching term and reserve **handshake** for the actual protocol or exact retained type names.
- [ ] Keep implementation links pinned to `release/6.0.0` when documenting the Learning 1.0 production baseline.
Expand Down
54 changes: 33 additions & 21 deletions tools/validate-asibackbone-6-api-references.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,17 @@

return AsiBackboneApiReferenceValidator.Run();

static class AsiBackboneApiReferenceValidator
static partial class AsiBackboneApiReferenceValidator
{
private const string ApiBoundaryRelativePath =
"docs/getting-started/asibackbone-6-api-boundary.md";

private static readonly HashSet<string> HistoricalSymbolReferencePaths = new(StringComparer.Ordinal)
{
ApiBoundaryRelativePath,
"docs/getting-started/learning-1-asibackbone-6-compatibility.md"
};

private static readonly HashSet<string> ForbiddenCurrentSymbols = new(StringComparer.Ordinal)
{
"AsiBackboneAcknowledgmentChallenge",
Expand Down Expand Up @@ -116,7 +122,8 @@ static class AsiBackboneApiReferenceValidator
"IAsiBackboneSignatureVerificationService",
"IAsiBackboneSigningService",
"InMemoryAuditResidueLifecycleStore",
"RequireGovernancePolicy"
"RequireGovernancePolicy",
"RequireGovernancePolicyAttribute"
};

private static readonly HashSet<string> TextExtensions = new(StringComparer.OrdinalIgnoreCase)
Expand All @@ -136,13 +143,15 @@ static class AsiBackboneApiReferenceValidator
".yml"
};

private static readonly Regex IdentifierRegex = new(
[GeneratedRegex(
@"\b[A-Za-z_][A-Za-z0-9_]*\b",
RegexOptions.Compiled | RegexOptions.CultureInvariant);
RegexOptions.CultureInvariant)]
private static partial Regex IdentifierRegex();

private static readonly Regex StaleImplementationLinkRegex = new(
[GeneratedRegex(
@"https://github\.com/AsiBackbone/AsiBackbone/(?:blob|tree)/(?!release/6\.0\.0(?:/|\b))[^\s)\]'>]+",
RegexOptions.Compiled | RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
RegexOptions.CultureInvariant | RegexOptions.IgnoreCase)]
private static partial Regex StaleImplementationLinkRegex();

public static int Run()
{
Expand All @@ -159,7 +168,7 @@ public static int Run()
}

var errors = new List<string>();
IReadOnlyList<string> textFiles = EnumerateTextFiles(repositoryRoot).ToArray();
string[] textFiles = EnumerateTextFiles(repositoryRoot).ToArray();

ValidateCurrentSymbolsAndLinks(repositoryRoot, textFiles, errors);
int packageReferenceCount = ValidatePackageReferences(repositoryRoot, errors);
Expand All @@ -185,43 +194,46 @@ public static int Run()
: $"{packageReferenceCount} AsiBackbone 6.x package reference(s)";

Console.WriteLine(
$"Validated AsiBackbone 6.0 API references across {textFiles.Count} instructional file(s): {packageSummary}.");
$"Validated AsiBackbone 6.0 API references across {textFiles.Length} instructional file(s): {packageSummary}.");
return 0;
}

private static void ValidateCurrentSymbolsAndLinks(
string repositoryRoot,
IEnumerable<string> files,
ICollection<string> errors)
List<string> errors)
{
foreach (string path in files)
{
string relativePath = NormalizeRelativePath(repositoryRoot, path);

if (string.Equals(relativePath, ApiBoundaryRelativePath, StringComparison.Ordinal) ||
string.Equals(relativePath, "tools/validate-asibackbone-6-api-references.cs", StringComparison.Ordinal))
if (string.Equals(relativePath, "tools/validate-asibackbone-6-api-references.cs", StringComparison.Ordinal))
{
continue;
}

string text = File.ReadAllText(path);
string[] lines = File.ReadAllLines(path);

for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
if (!HistoricalSymbolReferencePaths.Contains(relativePath))
{
string line = lines[lineIndex];
string[] lines = File.ReadAllLines(path);

foreach (Match identifierMatch in IdentifierRegex.Matches(line))
for (int lineIndex = 0; lineIndex < lines.Length; lineIndex++)
{
if (ForbiddenCurrentSymbols.Contains(identifierMatch.Value))
string line = lines[lineIndex];

foreach (Match identifierMatch in IdentifierRegex().Matches(line))
{
errors.Add(
$"{relativePath}:{lineIndex + 1} uses removed or renamed 5.x symbol '{identifierMatch.Value}'.");
if (ForbiddenCurrentSymbols.Contains(identifierMatch.Value))
{
errors.Add(
$"{relativePath}:{lineIndex + 1} uses removed or renamed 5.x symbol '{identifierMatch.Value}'.");
}
}
}
}

foreach (Match linkMatch in StaleImplementationLinkRegex.Matches(text))
foreach (Match linkMatch in StaleImplementationLinkRegex().Matches(text))
{
int lineNumber = GetLineNumber(text, linkMatch.Index);
errors.Add(
Expand All @@ -232,7 +244,7 @@ private static void ValidateCurrentSymbolsAndLinks(

private static int ValidatePackageReferences(
string repositoryRoot,
ICollection<string> errors)
List<string> errors)
{
var centralVersions = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
var references = new List<PackageReference>();
Expand Down Expand Up @@ -318,7 +330,7 @@ private static int ValidatePackageReferences(

private static void ValidateScopeNotices(
string repositoryRoot,
ICollection<string> errors)
List<string> errors)
{
string[] noticePaths =
{
Expand Down
Loading