Skip to content

Release v0.6.0

Choose a tag to compare

@github-actions github-actions released this 06 Sep 21:46
37a62f8

Summary

Migrates the Arc backend, EF Core and identity capabilities out of the legacy .ai/skills tree into self-contained canonical sources under skills/, and lists them on public-arc, public-arc-ef-core and public-arc-identity. Every framework claim was re-verified against Arc v22.10.4, Fundamentals 7.18.2 and Chronicle 16.39.1 rather than carried over, which corrected a number of claims the legacy corpus shipped. (#175)

Command validation is deliberately not migrated here. cratis-arc-command-validation and cratis-chronicle-event-constraints read from the one legacy source .ai/skills/add-business-rule, and a source record names exactly one path, so the two have to migrate together. The read-model injection rules a command needs are carried on cratis-arc-command instead. (#175)

Added

  • cratis-arc-command — the [Command] record, how each Handle() return shape is dispatched, Provide(), what may reach the causation chain, and the generated proxy contract, with references for handler shapes, the command result, read-model injection and proxy generation (#175)
  • cratis-arc-command-execution — running an existing command through ICommandPipeline, its overloads, validation severity filtering and how to read a CommandResult (#175)
  • cratis-arc-query-paging — which read-model query return shapes Arc pages, the exact query-string contract, the per-provider sorting differences, and the paged frontend hooks (#175)
  • cratis-arc-observable-query-http — inspecting an observable query with plain HTTP, wait-for-first-result, Server-Sent Events or long polling, including the status codes and payload shape (#175)
  • cratis-arc-ef-core-migration — the DbContext base types Arc provides, what actually makes an EF Core read model injectable into a command, the cross-database column helpers, JSON columns, and the observation story (#175)
  • cratis-arc-authentication-authorization-and-identityIProvideIdentityDetails and /.cratis/me, the three authorization attributes Arc evaluates, the forwarded-principal authentication contract, tenant resolution and the React identity surface, with references for authentication, authorization, tenancy, frontend and local development (#175)

Changed

  • public-arc, public-arc-ef-core and public-arc-identity now list real capabilities and move from planned-source-migration to preview-source-candidate (#175)
  • public-arc-react now composes public-arc, and engineering-arc-react now composes engineering-arc — resolving either React profile previously dropped every backend Arc capability it depends on (#175)
  • cratis-arc-observable-query-http is no longer excluded from the public review candidate package: the rewritten source carries no host, port or route from any private environment (#175)

Fixed

  • The client ValidationResult shape: it carries members: string[] (camelCased on purpose) and a numeric severity, not a propertyName and a string severity. A concept validator's failure is attributed to the field holding the concept, not to its inner Value (#175)
  • A non-nullable read model that does not exist for a command's resolved key raises ReadModelDoesNotExistForCommand, an IValidationFailure surfacing as HTTP 400 with reason DependencyUnavailable — not CannotResolveValidatorDependency, which is only the fallback for an unregistered type or a missing key (#175)
  • ARCCHR0009's own guidance is to mark or rename a property whose name reads as a secret, not to suppress the diagnostic (#175)
  • The proxy generator does not extract Must(...) rules, so validateClientSide() can pass where execute() still fails validation (#175)
  • CratisProxiesSkipOutputDeletion already defaults to true; setting it is not a fix for the generator deleting files (#175)
  • An unknown sortby is a server error on an IQueryable query, while the MongoDB and EF Core observe paths deliberately degrade to unsorted (#175)
  • A command proxy's use() returns three elements, and an observable query's useWithPaging returns four rather than five (#175)
  • Waiting for an observable's first result answers 202 when it is not ready, 408 on timeout and 500 on completion without a value, with a 30 second default (#175)
  • Arc ships no migration tooling of its own — no design-time DbContext factory, no migration runner, no table-name constant convention. The hand-written-migration, WellKnownTables and ApplyAllMigrations conventions the legacy skill taught belong to one application, not to Arc (#175)
  • A [ReadModel] entity is only injectable into a command when its DbSet sits on a ReadOnlyDbContext; on a plain BaseDbContext it is registered and queryable but silently never resolved (#175)
  • WithEntityFrameworkCore() with no connection string discovers nothing, because both discovery gates test it against the empty default (#175)
  • AuthorizeAttribute.Policy and AuthenticationSchemes are declared but never read, so [Authorize(Policy = "...")] enforces nothing. Arc evaluates exactly three attributes and there is no [Policy], [Scopes] or [Claims] (#175)
  • Default access differs by hosting model: self-hosted Arc.Core is authenticated-by-default once any IAuthenticationHandler exists, while under ASP.NET Core nothing ever calls RequireAuthorization (#175)
  • IdentityDetails.Details is object, not generic; IProvideIdentityDetails<TDetails> is a member-less marker that only captures the type (#175)
  • Arc has no OpenID Connect, no JWT bearer, no development identity provider and no .cratis/.ai local identity route (#175)

Security

  • The forwarded x-ms-client-principal header is base64, not a signature, and Arc does not check who sent it — every migrated identity source states that boundary and what it means for deployment (#175)
  • The .cratis-identity cookie is deliberately not HttpOnly, so RequireRole hides UI and never protects data; every rule it expresses must also exist on the server (#175)
  • /.cratis/users and /.cratis/tenants are anonymous and mapped unconditionally, so a provider returning real users or tenants publishes them (#175)
  • Arc's subdomain tenant resolver falls back to a caller-controlled header when the host does not match (#175)