Dev - #90
Conversation
…, blur) Background was a first-class type in the recipe model and parsed from URL ?bg= parameters, but the pipeline never read shape.Background — it was parse-but-ignore. BackgroundComposer now closes the loop: - Triggers only when bg is non-transparent + Fit.Contain has a fully resolvable target canvas (preserves the transparent-default behavior every existing test relies on). - Builds a new Rgba32 canvas, paints it per BackgroundKind, then composites the shaped image at the requested Position. - Solid: explicit color from the recipe. - Dominant: 1x1 box-resample of the source — fast average that reads as "dominant" for photographs and covers without a real k-means pass. - Auto: border-strip average on a 16x16 down-sample — stable against per-pixel noise, cheap on full-res sources. - Blur: cover-resize a clone of the source to the canvas, Gaussian-blur at the requested radius (defaults to ~4% of the canvas short edge). The composer allocates a separate canvas instead of mutating the caller's image, so 'using var image' in ToBytesAsync/MaterializeAsync stays correct — the canvas is owned and disposed inside EncodeAsync.
15 new specs covering all four BG modes end to end: - BackgroundComposerSpec: solid+contain pad behavior, position-controlled offset, transparent-default no-op, fit=cover no-op, no-crop no-op, dominant/auto/blur color correctness, JPEG (no-alpha) fallback, cross-mode distinct outputs on a multi-color source. - MediaControllerSpec: ?bg=00ff00 and ?bg=blur through the URL parser + mutator allowlist + pipeline; bg-without-crop rejected with 400 in strict mode. - Fixtures.JpegWithBorder: green border + red center fixture for Auto bg verification (border sample != center sample). Tests use the resize-smaller-than-crop pattern (1200x600 -> Pixels(800,600) -> Resize(600,600) Contain) so the composer actually triggers — earlier drafts inadvertently picked dims where the shaped image already matched the canvas and the composer correctly no-op'd, producing spurious passes via source pixels happening to match expected bg colors.
Minor bump (new feature, no API break): bg=auto/dominant/blur now do actual canvas compose work. The pipeline contract is unchanged — only the previously-ignored transparent-default keeps its prior semantics.
…rop) ResizeCover(w, h) built two steps: ResizeStep(w, h) at stage Size (50) AND ShapeStep(crop: Pixels(w, h), fit: Cover) at stage Shape (40). Stage ordering ran Shape first, which took the Pixels crop branch and chopped a literal w*h rectangle out of the source center — no scaling. The subsequent Resize then no-op'd on the already-sized image. A 480x480 article-card thumbnail from a 1920x1080 cover was reduced to the middle 480x480 pixels of the source, not a downscaled version of it. Fix: drop the redundant Pixels crop. Resize + Fit.Cover maps natively to ImageSharp's ResizeMode.Crop, which does scale-then-crop correctly. The same change applies to MediaRecipeBuilder.ResizeCover so config- declared recipes get the fix too. Regression test uses a bordered source (red border, green interior) and asserts the top-center pixel of the cover output is red — proof the border survived the downscale. A literal pixel-chunk crop would have yielded green pixels with no trace of the border. Bumps Koan.Media.Core + Web to 0.11.1. Koan.Media.Abstractions stays at kernel version 0.8.2; it needs a repack because MediaRecipeBuilder also moved.
…o break silent overload trap When TKey is bound to string, C# overload resolution prefers the non-generic Remove(string query, ct) over the generic Remove(TKey id, ct). Every caller that did `Foo.Remove(entity.Id, ct)` against a string-keyed Entity silently shipped the id to the repository as a query expression and got back "NotSupportedException: String queries are not supported by this repository" the moment the path actually ran against Mongo/Postgres. Rename both overloads to RemoveByQuery so Remove always means "by key" and the verb is explicit when you mean "by query expression". No internal caller intentionally used the old form, and the rename automatically fixes latent timebombs across: - Koan.AI.Models.ModelService (ModelEntry.Remove(modelId, ct)) - Koan.Data.AI EmbedJob<T>.Remove(job.Id!, ct) (4 sites) - Koan.Data.AI EmbeddingState<T>.Remove(state.Id!, ct) - Koan.Service.KoanContext IndexingJobMaintenanceTask (2 sites) - Koan.Rag RagIngestionWorker Audit also confirmed Entity.Remove was the ONLY method in the framework with this collision shape — Get/Patch/Delete are key-only, Query/Count/QueryStream are query-only by design. Full audit table in chat thread. Data.Core test suite: 17 pre-existing vector/transaction flakes, identical count before and after the rename. Zero new regressions.
… only claims bodies it can actually handle Previously CanReadType was the only gate: any IEntity<> POST routed through this formatter even when no Terminal input transformer was registered for the (entity, content-type) pair. ReadRequestBody then returned NoValue and the controller's [FromBody] argument bound null, breaking standard JSON upserts for any assembly that pulled in Koan.Web.Transformers solely for output enrichers. CanRead now does the second-stage runtime check against the registry. If no transformer is registered for this entity+content-type, return false and let the default System.Text.Json formatter handle the body as it would in a project without Koan.Web.Transformers loaded.
…ers 0.8.2->0.8.3 Data.Core minor bump for the Remove->RemoveByQuery rename (technically a public API removal even though zero callers depended on it). Web.Transformers patch for the CanRead guard fix.
…ion) Five vulnerable transitives + one direct vuln fixed via coordinated bumps and explicit transitive overrides. Verified via `dotnet list Koan.sln package --vulnerable --include-transitive` — zero remaining advisories across all 154 projects. Changes: OpenTelemetry SDK (CVE-2026-40891, CVE-2026-40182, CVE-2026-42191, CVE-2026-40894): Koan.Core, Koan.Web — bump OTel from 1.13.x to 1.15.x matching set: Extensions.Hosting 1.13.1 -> 1.15.3 Exporter.OpenTelemetryProtocol 1.13.1 -> 1.15.3 Instrumentation.AspNetCore 1.13.0 -> 1.15.2 Instrumentation.Http 1.13.0 -> 1.15.1 Instrumentation.Runtime 1.13.0 -> 1.15.1 Snappier (GHSA-pggp-6c3x-2xmx, HIGH): Koan.Data.Connector.Couchbase — add explicit Snappier 1.3.1 override. CouchbaseNetClient 3.8.1 still pulls Snappier 1.2.0 (in affected range <= 1.3.0); 1.3.1 is API-compatible. SharpCompress (GHSA-6c8g-7p36-r338) + MongoDB.Driver bump: Koan.Data.Connector.Mongo, Koan.Data.Cqrs.Outbox.Connector.Mongo, Koan.Testing, Koan.Web.AdapterSurface.TestKit, Koan.ZenGarden.Tests: MongoDB.Driver 3.5.0 -> 3.8.1 SharpCompress override -> 0.48.1 (outside affected <= 0.47.4 range). Mongo uses SharpCompress for snappy stream decompression, not the affected WriteToDirectory extraction path — override is safe. HotChocolate (GHSA-qr3m-xw4c-jqw3, CRITICAL — was masked by OTel noise in build output, surfaced by the cleanup scan): Koan.Web.Connector.GraphQl: HotChocolate.AspNetCore 13.8.1 -> 13.9.16 HotChocolate.Execution 13.8.1 -> 13.9.16 BananaCakePop.Middleware 13.0.0 -> 16.0.3 (forced by HotChocolate 13.9.16 dep range; ExcludeAssets="all" preserved so UI middleware stays out of runtime). Regression checks: Data.Core tests: 89 passed / 17 pre-existing flakes — identical baseline. Media tests: 374/374 pass. Gposingway downstream build: green against the new vendor feed.
Kernel bump for Koan.Core OTel 1.15.x upgrade. Other Kernel packages (Data.Abstractions, Media.Abstractions, Orchestration.Abstractions, …) have unchanged source but repack at 0.8.3 to keep the dep graph internally consistent — every package built after this commit declares deps at >= 0.8.3 on its kernel siblings. Periphery patch bumps for source changes: Koan.Web 0.8.1 -> 0.8.2 (OTel set) Koan.Data.Connector.Couchbase 0.8.1 -> 0.8.2 (Snappier override) Koan.Data.Connector.Mongo 0.8.1 -> 0.8.2 (Mongo + SharpCompress) Koan.Data.Cqrs.Outbox.Connector.Mongo 0.8.1 -> 0.8.2 (Mongo + SharpCompress) Koan.Web.Connector.GraphQl 0.8.1 -> 0.8.2 (HotChocolate fix)
…ame version
Earlier this session bumped KoanKernelVersion 0.8.2 -> 0.8.3 to reflect
the OpenTelemetry 1.13 -> 1.15.3 upgrade in Koan.Core. That bump cascades
through Directory.Build.targets, recomputing AssemblyVersion for every
Kernel package even though only Koan.Core's source changed.
Net effect: cross-package skew that the runtime can't bind through.
* Periphery packages packed AFTER the bump (Koan.Web 0.8.2 here) have
their dlls compiled with binary IL refs to Cache.Abstractions 0.8.3.0,
Core 0.8.3.0, etc.
* Periphery packages packed BEFORE the bump (Data.Core 0.9.0) have
nuspecs declaring Cache.Abstractions >= 0.8.2.
* Web's nuspec only declares its DIRECT deps; Cache.Abstractions reaches
Web transitively via Data.Core, so it isn't listed.
* NuGet picks the lowest version that satisfies all constraints across
the graph: Cache.Abstractions 0.8.2 (per Data.Core's nuspec).
* Container deploys Cache.Abstractions 0.8.2.0; Web.dll tries to bind
to 0.8.3.0 at runtime -> FileNotFoundException.
The right answer for a Kernel-version bump is: every consuming Periphery
must also be repacked so its nuspec captures the new kernel range. That's
a 30+ package cascade for a single OTel upgrade — not worth the churn.
Instead: keep kernel at 0.8.2 and ship the OTel change as a same-version
Koan.Core repack. The runtime contract is unchanged; consumers bust their
NuGet package cache to pick up the refreshed dll. The
versions.props comment now documents this constraint so the next person
who reaches for a kernel bump thinks twice.
The Media docs were last touched at v0.9.0 and predate the overlay system (shipped 0.10.0), smart backgrounds (0.11.0), and source-side pre-decode limits (in MediaWebOptions since 0.10.1). Surgical updates: reference/media/index.md: - framework_version: v0.9.0 -> v0.11.1 - Drop "(v2)" markers on the Overlay pipeline stage and MutatorKind row — both shipped. Overlay row now lists the actual sub-params (size/position/padding/opacity/rotate/recipe). - Background table: fix Auto and Dominant descriptions to match the actual implementation (16×16 down-sample border average; 1×1 box-resample for dominant — k-means and per-source-hash caching were aspirational, not shipped). Note that smart bgs only fire with Fit.Contain + fully-defined target canvas. - Background mutator row in MutatorKind: document the bg-without-crop 400 rejection. - MediaWebOptions table: add MaxSourceMegapixels and MaxFrameCount, including the X-Koan-Media-LimitExceeded diagnostic header values. - Future/Reserved: drop the now-shipped "overlay" and "bg=blur/dominant" bullets; add accurate notes for what's still deferred (BlurHash placeholders, per-source-hash sample cache). guides/media-recipes-howto.md: - framework_version: v0.9.0 -> v0.11.1 - §3 Shape/Fit/Position/Background: add inline samples for Background.Blur(), .Dominant(), and .Auto() — previously only Solid + Transparent were demonstrated, leaving the smart-bg factories undiscoverable. - §3: add the matching ad-hoc URL examples and call out the bg-without-crop rejection. - §3 "Why this works": new paragraph describing the composer's separate-canvas pass so readers understand why the original image isn't mutated. Overlays still don't have a section in the guide — that's a separate write-up worth doing when the overlay surface stabilises in a use case beyond the framework's own tests.
Previous commit deferred this on the rationale that overlays only
ship in the framework's own tests. User overruled — add the section
now so readers discover the feature exists even before Gposingway
puts it to work.
New §4 follows the Concepts / Recipe / Sample / Why / Usage rhythm
the rest of the guide uses. ~80 lines, covers both verbs (media
overlay + text overlay), the IOverlayResolver / KoanFontRegistry
wiring requirements, and the URL grammar. Stops short of the full
parameter surface — links to the reference for the sub-param zoo
(overlay.size, overlay.position, overlay.recipe, etc.).
Renumbered §4 -> §10 to keep the flow Concepts -> Recipes -> HTTP
-> Multi-variant -> Probing -> Introspection -> What's Next.
Two cross-references updated:
- §0 prereqs "We'll wire that in §5" -> §6 (HTTP Surface shifted)
- §5 "introspection endpoint (§5)" -> §9 (also fixes a
pre-existing typo — that ref always pointed to introspection,
not the HTTP surface, even before the overlay insert)
Adds QueryOptions.Predicates (List<LambdaExpression>) and the AddPredicate<TEntity> extension so IRequestOptionsHook<TEntity> implementations contribute server-side predicates that AND-compose with the user's ?filter= at query-execution time. Adapters that support ILinqQueryRepository push the composed expression down natively; pagination headers, X-Total-Count, and Link rel="next" all reflect the post-predicate set. Replaces the post-fetch in-memory filtering anti-pattern in IEmitHook/ICollectionHook for visibility, tenancy, soft-delete, and per-role scoping concerns. When predicates contribute, free- text Q is dropped (the two paths can't be composed at framework layer) with an informational log. QueryPredicateComposer.AndAll<TEntity> handles AND-chain wiring with parameter rewriting via ExpressionVisitor so the resulting tree is well-formed for LINQ providers. Covered by RequestOptionsHookPredicateSpecs end-to-end against the InMemory adapter — anonymous / authenticated / admin tiers, ?filter= AND-composition, pagination correctness, body-query path, and the load-bearing security claim that ?filter= cannot escape the hook predicate. Koan.Web bumped 0.8.2 -> 0.8.3 (additive surface, no break). See docs/decisions/WEB-0068-query-options-predicates.md for the full design + alternatives considered.
BuildIn materialized the array as List<object>, which the LINQ provider
rejected for Enumerable.Contains<TMember> whenever TMember was a value
type or enum ("cannot be used for parameter of type IEnumerable<TMember>").
Build a strongly-typed List<TMember> reflectively so $in works for enum-,
int-, GUID-, etc.-typed members, not just strings.
Adds an opt-in IMediaOutputCache consulted by MediaController before the resize/re-encode pipeline and populated write-through after a render, so repeat requests for the same (media id, recipe fingerprint) skip the pipeline entirely. Default is a no-op; a filesystem-backed implementation activates via Koan:Media:Web:OutputCache (Enabled + Path). The cache key is the framework's own content-identity (id + recipe fingerprint), so it is exactly as correct as the existing ETag-based HTTP caching: a recipe edit bumps the fingerprint, the key changes, and old entries orphan rather than serve stale. Entries are one file per render (format-as-extension, no sidecar), written via temp-file + atomic rename, and all IO is best-effort so a cache fault never faults a response. Bumps Koan.Media.Web 0.11.1 -> 0.11.2.
Adds the Koan:Media:Web:OutputCache option + MediaOutputCacheOptions subsection to the media reference (keying, write-through, no-eviction, swappable IMediaOutputCache), a how-to note on enabling it, and an implementation-status note on MEDIA-0004 clarifying what shipped in 0.11.2 (opt-in filesystem cache, fingerprint invalidation, no GC sweep; warm endpoint + Eager pre-warm still unimplemented).
Replace the single Job table plus store-resolver apparatus with table-per-type job entities: Job<T> : Entity<T> carrying typed Context/Result, policy virtuals (Lane, Retry, DeriveCoalesceKey, HostTag), job.Submit()/static Push, typed JobRef dependencies, and a generic JobDispatcher<T> runtime. Collapses the store layer (EntityJobStore/IJobStore/JobStoreResolver/InMemoryJobStore) into Entity<T> + JobTypeRegistry + JobCancellations, and removes the run-builder / recipe / web-mapper scaffolding the old model needed. Subsumes JOBS-0002 (concurrency lanes, coalescing, Push, delayed visibility). Breaking change on pre-1.0, so Koan.Jobs.Core bumps 0.8.1 -> 0.9.1; 0.9.1 also drops the internal RecoveryProbe/DummyJob placeholders so JobTypeRegistry no longer discovers phantom collections.
A concrete entity that inherits from another concrete entity (Model2 : Model where Model : Entity<Model>) silently splits writes from reads: Save infers the derived compile-time type and writes to the Model2 set, while Get and the other inherited Entity<Model> statics read the Model set. The row persists but is unreadable through the type's own accessor, with no error. EntityShapeGuard.EnsureOwnRoot, called from DataService.GetRepository (the single chokepoint every read, write, and delete funnels through), now throws an InvalidOperationException naming the offending type and the fix. Validation is cached per type. The entity how-to gains a "Sharing Shape Across Entities" section documenting the correct shape: each entity is its own Entity<T> root, sharing fields through a generic base, preserving bare .Get(id) with no codegen.
….10.0) Add an optional second concurrency tier within a lane: a per-partition cap alongside the existing lane-global cap. A job exposes Job.LanePartition; the lane registry acquires the partition permit BEFORE the lane-global permit, so a hot partition's waiters never occupy global slots and starve other partitions. Lanes without MaxConcurrencyPerPartition behave exactly as before (additive + opt-in). - JobLaneOptions: MaxConcurrencyPerPartition + PartitionOverrides - Job<T>.LanePartition (virtual) + internal accessor; JobDispatcher passes it - JobLaneRegistry: per-(lane,partition) gates, partition-first acquisition, PartitionCapacityFor (override > lane default > off) - Specs: per-partition capping, lane isolation, and the key guarantee that a hot partition's waiters don't consume lane-global slots Bumps Koan.Jobs.Core 0.9.1 -> 0.10.0.
feat(data)!: unified filter pipeline — Filter AST, QueryDefinition, contract inversion (DATA-XXXX) Break-and-rebuild of the entity query path (greenfield, no back-compat). Core (green, 31 unit specs): - Promote the Vector filter AST into a provider-neutral Koan.Data.Abstractions.Filtering: Filter/FieldFilter/AllOf/AnyOf/Not/ClrFilter + FieldPath + FilterOperator + FilterValue. - Two front-ends converge on one AST: JsonFilterParser (DSL) + LinqFilterCompiler (Expression), with ClrFilter escape for un-liftable lambdas. - InMemoryFilterEvaluator = bounded fallback floor AND convergence oracle; locked null/Nin semantics. - FieldPathResolver + FilterValueConverter (fail-loud coercion). - FilterCapabilities + IFilterTranslator + FilterSplitter (result-preserving partial-pushdown split). Contract (frozen): - QueryDefinition (Filter+Sort+Projection+Page+Count+Partition) replaces object?-query + DataQueryOptions. - IQueryRepository (one method) replaces ILinqQueryRepository(+WithOptions)/IStringQueryRepository(+WithOptions). - Per-axis RepositoryQueryResult envelope (FilterHandled/SortHandled/PaginationHandled/ProjectionHandled). - STRATEGIC A: adapter = translator+executor; FilterPushdownCoordinator owns split/residual/sort/paginate-AFTER (structurally fixes the relational mis-pagination bug; gives every adapter a bounded floor). - IDataRepository is writes-only; IRawQueryRepository is the explicit raw escape hatch. - Deleted DataQueryOptions, CountRequest, and the 4 old query interfaces. Orchestrator + DX (preserved): - Data.cs/Entity.cs lower entity-first LINQ/DSL into QueryDefinition; Todo.Query(lambda) unchanged, Todo.Query(string)=DSL, new Todo.QueryRaw(...) for provider-native. Adapters migrated (green): InMemory, JSON, Redis (Full floor via InMemoryFilterEvaluator). Remaining (next): relational PG/SqlServer/Sqlite (native JSON containment), Mongo, Couchbase; web endpoint; vector retype; convergence suite; ADR supersession. Fixes the reported $in-on-List<string> crash at the model level (now HasAny overlap). @
feat(web)!: route EntityController through QueryDefinition + Filter AST (DATA-XXXX)
- EntityEndpointService GET/POST/DELETE-by-query now parse the JSON filter DSL via
JsonFilterParser into the unified Filter AST and build a QueryDefinition; hook predicates
AND-compose via the new QueryFilterComposer (lowered to AST), free-text Q routes to QueryRaw.
- Filter parse / unknown-field / unsupported-operator now map to 400 (not 500).
- Fix POST /query $options key bug ("" -> "$options") so body ignoreCase is honoured.
- Delete JsonFilterBuilder + QueryPredicateComposer (superseded by AST + QueryFilterComposer).
- EntityController HTTP contract (?filter=/?sort=/?q=/page/size/set/$options, POST /query) unchanged.
Koan.Web + Koan.Web.Extensions build green.
@
fix(web): QueryFilterComposer accepts IReadOnlyList<LambdaExpression> (hook predicates) Hook predicates arrive as LambdaExpression; cast to Expression<Func<TEntity,bool>> per entry (fail-loud, matching the old QueryPredicateComposer contract) before lowering to the Filter AST. Koan.Web now builds green. @
feat(cqrs,web-ext): migrate consumers to unified IQueryRepository contract (DATA-XXXX) - CqrsRepositoryDecorator implements IQueryRepository (Query/Count over QueryDefinition), delegating to the routed read repository; drops ILinqQueryRepository/IStringQueryRepository. - EntitySoftDeleteController: filter is the JSON DSL via Data.Query(string) on every adapter (drops the dead IStringQueryRepository gate). Koan.Data.Cqrs + Koan.Web.Extensions build green. @
feat(data)!: migrate relational/Mongo/Couchbase adapters to unified IQueryRepository (DATA-XXXX) All 8 data adapters are now translator+executor on the unified contract. Relational (shared Koan.Data.Relational): new SqlFilterTranslator (Filter AST -> WHERE, parameterized by ILinqSqlDialect + per-adapter column resolver) + RelationalFilterCapabilities; ILinqSqlDialect gains JsonArrayContains/JsonArrayLength; LinqWhereTranslator deleted. Sqlite json_each / Postgres jsonb / SqlServer OPENJSON for collection containment. Each adapter implements IQueryRepository + IRawQueryRepository; deletes the ILinq/IString query interfaces, the 9 NotSupportedException load-all fallback blocks, ComputeSkipTake, CountRequest. Collection ops (Has/HasAny/HasAll/HasNone/Size) push down natively; nested paths + ignoreCase declared OUT of caps -> coordinator in-memory floor (preserves convergence with the oracle). Mongo: MongoFilterTranslator (Filter AST -> FilterDefinition) + StringCollectionElementConvention carving List<string> elements out of the global GUID serializer; removed TryBuildGuidFilter walker. Couchbase: CouchbaseN1qlFilterTranslator (ANY..SATISFIES) replaces the LINQ translator that threw 500 on collection Contains; raw N1QL behind IRawQueryRepository; GUID "N"-form fix. null/Nin/HasNone honored to match InMemoryFilterEvaluator (the convergence oracle). All six projects build green. @
feat(cache)!: migrate CachedRepository to unified IQueryRepository contract (DATA-XXXX) CachedRepository implements IQueryRepository (Query/Count over QueryDefinition) + IRawQueryRepository, both delegating to the inner repository (the id-keyed L1/L2 cache cannot satisfy arbitrary filters). Dropped ILinqQueryRepository(+WithOptions) and IStringQueryRepository(+WithOptions) and their query overloads. All caching behavior unchanged: GetOrSet/GetOnly/SetOnly/Invalidate strategies, per-request EntityContext.CacheBehavior override, write invalidation, key templating, CachingBatchSet. Koan.Cache builds green — unblocks dependent cache work. @
test(data): cross-architecture convergence acceptance gate (DATA-XXXX §5.4) Proves the unified filter pipeline is result-preserving for ANY adapter pushdown boundary. For each filter in a canonical corpus (Widget.Tags=List<string> + scalar/enum/nullable shapes) and each capability profile bracketing the real adapters — Full (InMemory/JSON/Redis), Relational (PG/SqlServer/Sqlite), ScalarOnly (JSON-blob), CollectionOnly, None — the split -> push -> in-memory-residual-floor -> finalize pipeline must return the SAME entity ids as the in-memory oracle evaluating the whole filter. 18 filters x 5 profiles + a paginate-after-residual invariant = 19 specs, all green, zero infrastructure. Covers the original $in-on-collection bug, $all/$nin/$size/contains on collections, scalar in/nin/ne/range/between/enum/wildcard/exists, and and/or/nor composition. The container-backed per-adapter ARCH-0079 specs reuse this corpus against live stores, gated by adapter availability. @
…IA-0005) With TreatWarningsAsErrors=true on the test tree, the obsolete-warning on ExtractFrame became hard build failures. Migrate six test files to Sample(new FrameSelector.Index(n)) - the canonical form per MEDIA-0005 section Migration. ConfiguredRecipeBinder and MediaUrlParser tests now assert SampleStep / Selector shape directly; RecipeJsonSerializer asserts the canonical "sample" op slug. All 375 tests pass. Files: - Specs/Pipeline/PipelineExecutionSpec.cs - Specs/Pipeline/MaterializeBundleSpec.cs - Specs/Registry/ConfiguredRecipeBinderSpec.cs - Specs/Registry/MediaRecipeRegistrySpec.cs - Specs/Registry/RecipeJsonSerializerSpec.cs - Specs/Routing/MediaUrlParserSpec.cs
… (MEDIA-0005) Cover the seven test areas the ADR's section "Test coverage requirements" calls out: kind threading, Sample collapse, encoder gate refusal, Sample no-op on Raster, encoder Accepts matrix, KindMismatch payload shape, ExtractFrame source-compat alias, FlattenTo expansion, Vector forward-derive, planner does-not-reorder. 21 additional tests; total now 396.
chore(vector): keep vector filter path separate; delete dead LINQ lifter (DATA-XXXX) Reverted the FilterToVectorFilter bridge: entity filtering is typed (FieldPathResolver binds to a CLR type and fails loud on unknown fields; FilterValueConverter coerces to leaf type) while vector metadata filtering is schemaless (arbitrary fields under a metadata blob). Forcing one front-end is wrong — the schemaless parser is a distinct concern, not duplication. The node-model collapse (VectorFilter nodes/operator enum -> the unified Filter AST, repointing the 5 provider translators) remains worthwhile and is deferred to a scoped vector session that writes a translator conformance suite first. Deleted the unused VectorFilterExpression LINQ lifter (dead code). @
…wto, framework-utilities, CLAUDE.md jobs-howto §10: the Failed/Dead-kept-forever line was the pre-§19 behavior — now bounded by FailedAfter (30d) + RetainPerWorkType cap; flagged as a behavior change. §13 quick-ref gains the JobsOptions tuning knobs. framework-utilities + CLAUDE.md durable-tier notes updated (retention + pushed-down reads + the window-the-source guidance).
…iorSuite (ARCH-0079) The §19 behaviors (status-filter push-down, FIFO-head claim, retention window+cap, CountActive, cursor-conveyor) now live in the shared JobBehaviorSuite, seeded via the IJobLedger seam (not JobRecord.Save) so they're consistent on the in-memory tier (dictionary ledger) and every durable tier. Standalone RetentionSpec/ConveyorSpec removed (folded in); the SQLite-only 100k HighVolumeScanShapeSpec stays as the perf soak. Verified: in-memory 44, SQLite 50, Postgres 40. Also fixed the Postgres fixture, which (unlike its Mongo/SqlServer siblings) never disabled readiness gating — across the larger suite's rapid host churn it timed out and failed ALL 40 specs (~17s each); disabling it = 40/40 in 7s.
…edger predicates Mongo persists the JobStatus enum by NAME, so Status<Completed / Status>=Completed are lexicographic, not numeric — NonTerminal()/CountActive returned wrong results (count_active returned 0). Replace ordering comparisons with explicit equality sets (NonTerminal/Terminal/ActiveOf/TerminalOf); equality translates on every store. Caught by the cross-tier suite (ARCH-0079).
…ur-writes probes The harness cleared between specs via RemoveAll(Optimized)=Fast, which on Mongo is drop-and-recreate; repeating that DDL across the suite's rapid host churn flakes. Clear via RemoveStrategy.Safe (DeleteMany) — no DDL, reliable on every tier. ReadYourWritesProbe proves the Mongo data layer is consistent for both insert and update (0 misses/200) — ruling consistency OUT as the cause of the chain-claim flake.
…, isolate the flake) Reproduce the orchestrator's chain hop at the ledger level (settle predecessor Running->Completed + append same-WorkId successor, then claim) and measure each read independently. 0 misses across 100 single-host hops AND 25 fresh-host cycles. Combined with the read-your-writes probes, this proves the jobs claim/ledger and the Mongo data layer are correct; the intermittent suite flake is not reproducible in isolation -> an emergent test-harness artifact (diverse specs + shared container + rapid churn), not a code defect.
… + §19 cross-tier validation Comprehensive investigation note (docs/design): the jobs code + Mongo data layer are proven correct (4 diagnostics, 0 misses); the residual Mongo suite flake is an emergent, not-reproducible-in-isolation test-harness artifact. Captures what's ruled out, what was fixed (enum portability, DeleteMany clear, PG readiness), the reverted §17.2 wrong-turn, the KEY clue (PG/SqlServer share the same harness+container pattern and don't flake → Mongo-driver-specific under churn), candidate root causes, and architectural fix options (shared-host-per-class recommended). JOBS-0005 §19 status updated with the cross-tier validation result + pointer.
A chain successor is appended inside the predecessor's inflight task (SettleSuccess/FailureAsync -> _ledger.Append). DrainAsync did 'RemoveAll(completed); if (inflight.Count==0) break;' BEFORE awaiting inflight, so a successor appended in the window after ClaimNext returned null but before that RemoveAll was missed: the loop emptied inflight, broke, and never re-claimed. Stall dumps showed the successor Queued+visible+ungated with running=0 -- claimable work left unclaimed, violating DrainAsync's contract.
In-memory/SQLite are ~synchronous so the window is ~0 (never hit); Mongo's per-op latency widens it (intermittent); production's worker re-drains on a poll loop so it never surfaces there; a single host.Drain() in a test asserts immediately and fails. Fix: when a task just settled, re-claim before concluding the drain is done ('if (settled > 0) continue;'). A task completes only after its Append returns (acknowledged), so the re-claim is guaranteed to see the successor -- correctness for the contract on every store, not a test band-aid.
Validated: Mongo suite x8 green (was ~4/5 flaky); in-memory 44, SQLite 50, Postgres 40, SqlServer 40 all green (shared loop -> all tiers re-checked). Full investigation + the refuted hypotheses (MongoClient leak, xUnit parallelism, read-your-writes, exclusivity) in docs/design/jobs-mongo-suite-flakiness-investigation.md.
… rollup, atomic claim, native TTL Completes the three scale tiers §19 deferred. Capability-graded throughout: Tier 2 metrics = worker-batched node-sharded rollup (in-memory accumulate + periodic per-node-shard flush, NOT per-settle writes; opt-in); Tier 3 = atomic contention-free claim via FOR UPDATE SKIP LOCKED (PG/SqlServer) / FindOneAndUpdate (Mongo) with Optimistic fallback (SQLite/InMemory); TTL = computed ExpireAt + store-native TTL index on Mongo, periodic purge stays universal. Adds reusable data-layer capabilities (DataCaps.Claim.SkipLocked, DataCaps.Retention.TtlIndex, [Index(Ttl)]). Status: Proposed — [RATIFY] positions marked, impl pending.
…aim first, §20 addendum
… throughput metrics Each node accumulates terminal outcomes (Completed/Failed/Cancelled/Dead) in memory and periodically flushes its OWN JobMetric shard row (read-add-write, contention-free since only that node writes its shard; restart-safe since it adds, never overwrites). Dashboards read JobMetric.Summary in O(shards) — counts that SURVIVE retention (Tier 1 deletes the JobRecords; the rollup remains). Opt-in (JobsOptions.MetricsEnabled, default off) so the zero-config path stays write-free; active counts are unaffected (they come from the indexed ledger, §20.1). Flush rides the worker loop on MetricsFlushInterval + a final flush on graceful stop; bucket-age retention (MetricsRetention) rides the archive sweep. Cross-tier spec proves counts survive a purge. Green on all 5 tiers (in-memory 45, SQLite 51, Postgres 41, SqlServer 41, Mongo 45×3).
…nd-set claim (contention-free, single-execution) Adds a reusable Koan.Data primitive: IConditionalWriteRepository.ConditionalReplaceAsync(model, guard) + DataCaps.Write.ConditionalReplace — replace a row IFF the stored row still matches a guard (optimistic concurrency / CAS). The guard reuses each adapter's existing LinqFilterCompiler + filter translator, so there is no new SQL/dialect surface. Implemented on SQLite/Postgres/SqlServer (conditional UPDATE … WHERE Id AND <json-path guard>) and Mongo (single-doc ReplaceOne with _id ∧ guard — atomic, no transaction, works on single-node). RepositoryFacade forwards it; Data<T,K>.As<>() exposes capability interfaces. DataJobLedger now keeps SelectCandidates (the §17.2-settled lane/gate/exclusive filter, returning the runnable batch) and marks Running via the CAS (guard Status==Queued && Owner==null), falling through to the next candidate on a CAS-loss and to last-write-wins Optimistic where the capability is absent. This is contention-free and single-execution (two claimers can't both win a row) and preserves exclusivity unchanged. Refinement vs the ADR sketch (documented in §20.3): a conditional CAS-by-id, not literal FOR UPDATE SKIP LOCKED — because Koan stores entities as JSON documents and single-node Mongo's findOneAndUpdate can't express the cross-row exclusivity invariant; the CAS composes on every adapter. True SKIP-LOCKED distinct-rows is deferred to phase (d). Validated by a cross-tier concurrent_claimers_take_distinct_jobs_no_double_claim spec (8 claimers, 24 jobs, each claimed once): in-memory 46, SQLite 52, Postgres 42, SqlServer 42, Mongo 46.
… claim jobs-howto §10: opt-in JobMetric throughput rollup (survives retention) + the contention-free compare-and-set claim. framework-utilities: JobMetric.Summary + the distributed claim guarantee + the reusable IConditionalWriteRepository compare-and-set primitive (Data Access Helpers). CLAUDE.md: JOBS-0005 §20 scale-tier entry.
…(capability-graded) Adds [Index(Ttl = true)] to the data layer: a single absolute-expiry timestamp index that TTL-capable stores honor automatically. Carried on IndexSpec/IndexMetadata; Mongo builds it as CreateIndexOptions.ExpireAfter = 0 (and declares DataCaps.Retention.TtlIndex); the relational adapters SKIP TTL indexes (ProjectionResolver + RelationalModelBuilder) so a high-write table gets no redundant index. JobRecord gains ExpireAt, set at each terminal settle per outcome (Completed/Cancelled → +ArchiveAfter, Failed/Dead → +FailedAfter; null = retain indefinitely). The Tier 1 periodic purge remains the universal mechanism + the backstop; TTL just lets Mongo expire rows continuously at zero app cost. Specs: cross-tier a_settled_job_gets_an_absolute_expiry (ExpireAt = LastSettledAt + window) + a Mongo index_ttl_materializes_a_mongo_ttl_index (proves the wiring through real AddKoan; actual deletion is Mongo's background monitor, out of scope for a fast test). Green on all 5 tiers: in-memory 47, SQLite 53, Postgres 43, SqlServer 43, Mongo 48.
jobs-howto §10 + framework-utilities: Mongo TTL index on the per-outcome ExpireAt expires terminal rows continuously (periodic purge stays the universal backstop). CLAUDE.md: [Index(Ttl=true)] / DataCaps.Retention.TtlIndex primitive.
Comprehensive evidence-based assessment compiled as the baseline for the "fewer but more meaningful parts" consolidation: - 00-overview: executive verdict - L2 system with L3 islands (Cache, Jobs, Data inner ring, Web nucleus, Vector, Trust, Mcp) and an L1 public face - 01-cartography: 15 parallel pillar/corpus audits; systemic patterns (generational strata, dogfood deficit, doc/code drift, enforcement gap, gravity leaks); verified debris ledger - 02-philosophy-dx: canon extraction, 59-claim promise audit (22 TRUE / 12 PARTIAL / 25 FALSE), newcomer walk, ergonomics scores, surface census (2,351 public types), 18 duplicate-concept clusters - 03-maturity-model: 5-level ladder calibrated to the repo's own canon; every pillar placed - 04-recommendations: 8 tracks (truth, enforcement, cut waves, orchestration migration, in-flight migrations, fail-loud boot, kernel diet, docs system), longitudinal metrics dashboard, guardrails; riskiest items adversarially reviewed (corrected verdicts under evidence/stage4) - evidence/: raw structured findings from ~35 auditors (stages 1, 2, 4)
A copy-step misfire committed evidence/stage2 as a single file holding only surface.json. Replace with the proper directory: canon, promises, newcomer, ergonomics, surface, consistency.
…pt stash (06) 05-strategic-position (architect-reviewed): - Mission reframe: Rails for agentic, data-driven .NET apps (non-commercial, foundations-first); entity-as-universal-grammar named as THE asset - Agent-native thesis: one canonical way, fail-loud, shipped agent knowledge, dev-mode MCP introspection; wedge demo = an agent transcript - Second wedge: the data->AI seam as the flagship AI story; shed the MLOps verticals, orchestration-as-product, enterprise-governance persona, GraphQL/WebSockets, second-framework surfaces - Recorded decision: Newtonsoft.Json stays canonical (predictable polymorphic handling); the STJ island goes, defaults get documented loudly - Lesser-model session playbook (tier routing, evidence-first protocol, no-go zones, analyzer enforcement) - Premium-DX program: three-beat narrative spine, Diataxis IA collapse, "if it's in the docs it compiles" CI guarantee, dotnet new templates, concept-budget discipline, voice rules, llms.txt, samples-as-curriculum 06-prompt-stash: ready-to-paste, tier-routed prompts (T1/T2 lesser models, T3 frontier-only) covering every flagged issue and strategic capability - shared PREAMBLE, parameterized CUT-TEMPLATE + 14-row table, per-track recipes pointing at adversarially-verified evidence, coverage map.
Implements assessment Track A + 05 SS8 for the documents a newcomer (or agent) meets first. Every code snippet was verified against current src before writing (grep-evidenced); ghost APIs, dead links, phantom samples, and false version/validation stamps are gone. - README.md: three-beat narrative (entity -> application; intent -> capability; the app explains itself), working 60-second clone-and-run start, honest pre-1.0 status banner linking the maturity model, boot report as the demo, shipped differentiators only; removed Flow.OnUpdate, entity-static SemanticSearch, koan-framework org 404 links, v0.6.3 badge, Sylin-less package commands - docs/getting-started/overview.md: the golden path with an explicit 8-concept budget, canonical 4-line Program.cs as normative, correct verbs (Query/Remove), per-step concept pricing, Newtonsoft camelCase defaults stated loudly - docs/getting-started/quickstart.md: tombstone -> real quickstart (clone path recommended pre-1.0; from-scratch path with Sylin.* prefix stated) - docs/architecture/principles.md: rewritten as the real canon - capability- graded transparency, fail-loud, source-gen discovery, consolidation-era principles, and the "one canonical way" picks of record (Save/Remove/Query, KoanModule, Jobs scheduling, SSE, Newtonsoft); fictional APIs removed - docs/index.md: restructured navigation; assessment surfaced as a trust signal; honest status block - samples/README.md: truthful learning ladder (S0->S1->S10->S14), dogfood flagships labeled, broken/out-of-sln samples marked, phantom samples removed, in-the-solution = alive rule stated - samples/CATALOG.md: superseded banner pending regeneration from Koan.sln
…e prompt stash (07)
05 SS3.1 (architect-reviewed expansion): seven capabilities that make Koan
trustworthy and verifiable for agents - act one made it legible, act two lets
you delegate to it. Ranked by differentiation x fit x cost:
1. composition lockfile (behavioral SBOM; registry+provenance already collect it)
2. governed agent access (grants-as-entities, audit, coherence-epoch revocation
- the flagship; rides the Trust fabric direction)
3. conformance-by-declaration (the TestKit/oracle machinery pointed at app entities)
4. [Tenant] multi-tenancy primitive (capability-graded isolation; gated on Facet 3)
5. scales-down/sovereign deployment (AOT single binary, air-gapped; vs BaaS)
6. app-level AI evals (goldens as entities, runs as jobs; hard boundary vs the
shed MLOps lane)
7. agent-operable runtime (ops verbs as governed MCP tools; SC2 phase 2)
Plus the refused lanes: realtime sync/CRDTs, workflow engine, model ops, UI
scaffolding.
07-strategic-prompt-stash: frontier design-session cards for each (SC1-SC7) -
gap & assets, proposed Koan-idiom API shape + reference usage pattern (all
blocks explicitly marked as NON-EXISTENT design targets, excluded from the
snippet lint), DESIGN-PREAMBLE enforcing the ADR-first method and the seven
Koan DX tenets, per-card decision lists, boundaries, and cross-card
sequencing. Completed ADRs mint T1/T2 implementation cards back into 06.
…ld cards
The strategic stash is now actionable by lesser models end-to-end, per
direction: each card is a complete session (research -> plan -> implement ->
test -> document) with the design PRE-MADE - target shapes and reference
usage patterns embedded, DECIDED blocks closing the choices a small model
must never invent, DEFAULT blocks marking the few permitted deviations.
- Greenfield posture stated up front: break-and-rebuild welcome, no
[Obsolete] bridges or dual paths, superseded code deleted in-session;
the green ratchet is the only backward contract.
- Maturity-ordered into 5 composing phases:
P1 self-description (koan.lock.json composition lockfile; read-only MCP
introspection resources)
P2 verification (Sylin.Koan.Testing conformance kits - apps inherit a
trait-gated test suite)
P3 trust (grants-as-entities + audit + live revocation; governed ops
toolsets with dry-run-by-default destructive verbs)
P4 domain power ([Tenant] partition-substrate tenancy, hard-gated on
Facet 3; app-level AI evals with an explicit anti-MLOps boundary)
P5 reach (sovereign/AOT probe ending in a CI smoke + verified guarantee;
the agent-transcript wedge demo)
- Every card mandates the Koan DX tenets as acceptance criteria (entity
grammar, attribute-first, Reference=Intent, capability-graded, fail-loud,
boot-report line, concept budget) plus an ARCH-0079 integration spec and
a dogfood sample integration.
- SESSION-PREAMBLE adapted for full-lifecycle autonomy (push-through
defaults instead of stop-and-ask, revert only if green is unreachable).
- Cross-refs reconciled: 07 P1.2/P5.2 supersede 06 S1/S2; 06 S3/S4 remain
as Phase-4 gates; 05 SS3.1 and the indexes updated.
Compartmentalized, portable analysis of the three-project stack, separate from the per-project assessments: verified interlock ledger (code-derived, file:line), serialized-attention finding (one author, 192-day Koan gap = Zen+Koi construction window), synergy audit incl. the shared failure-mode process analysis, enabler-not-competitor doctrine + mission frame (capacitation, compute sovereignty), 7 ranked stack opportunities + 5 cross-project conflicts, target seam architecture (R1-R10), and a leverage plan built on a 5-item minimal truth set.
… (06)
Corrections: Koi TLS plane re-dated (worked pre-axum-0.8; regressed
silently while unexercised) and the serial-lane dogfooding model made
explicit - surfaces mature via downstream solutions, some outside these
repos; "dormant" means unguarded, not abandoned. Process finding
strengthened accordingly ("leave a guard at the door").
New 06-project-realignment.md: per-project identity/priority realignment
through the Epic + mission lens (Koi: trust made affordable, .internal +
koi trust promoted; ZG: hardware reclamation as capacitation; Koan:
democratizing software production + the exit audit); six mission-aligned
opportunities the per-project assessments missed (accidental sysadmin,
community GPU pool, repair-cafe channel, tested offline-first profile,
software-that-shows-its-work, data dignity); solution-driven maturation
formalized (surface ledger + rotation contract).
Self-contained, single-session prompts for lesser models on any provider (no memory/conversation access assumed): shared CHARTER (paths, mission + enabler doctrine, canon, session protocol, leave-a-guard rule, output contract) + 16 prompts phased to compose: A canon/ledger (E01 STACK-0001 ADR, E02 surface ledger) -> B seams (E03 koi publish closure, E04 zen published deps, E05 koi token/bind contract, E06 koan satellite inversion, E07 contract corpus) -> C trust column (E08 CSR enrollment, E09 moss client-auth + holes, E10 koan trust binding / tokens bound to certmesh identity) -> D proof (E11 two-machine demo, E12 self-description envelope) -> E agent-ready LAN + mission surfaces (E13 koi-mcp + composed demo, E14 zero-egress sovereign lane, E15 accidental-sysadmin profiles, E16 shows-its-work). Each prompt: Context with file:line ground truth, DECIDED/DEFAULT blocks, plan, verification, definition of done. Index + leverage-plan rule 3 updated to point at the stack.
Switch the release workflow from the retired Update-Versions.ps1 / versions.props / bumped-packages.txt flow to Nerdbank.GitVersioning: - Pack every packable csproj under src/ with -p:PublicRelease=true; nbgv stamps each package from its own version.json + git height. - Push all nupkg/snupkg with --skip-duplicate (unchanged packages are silently skipped by nuget.org -- idempotent by construction). - Date-based release tag (release/YYYY-MM-DD[-N]) replaces the retired kernel-version tag. - Delete build/versions.props (DEPRECATED banner sanctioned this once the workflow rework landed). - Delete Update-Versions.ps1, Show-VersionStatus.ps1, New-Release.ps1 (nothing references them in the new flow). - Rewrite docs/workbooks/nuget-publishing.md and versioning.md to describe the nbgv flow. Remaining ARCH-0085 item: section 4 dependent-closure release gate (verify that all packages a consumer needs are published together before any are visible). Not built in this change; tracked as ARCH-0085 follow-up.
Brings main's one unique commit (eff6aec, the PR #88 operational workbooks) into dev so the dev -> main promotion PR is conflict-free. Conflicts resolved taking dev's side -- dev already carries the workbook content and the nbgv release rework (ARCH-0085 item 3) that supersede PR #88's versions: - .github/workflows/release-on-main.yml (content) - docs/workbooks/{README,nuget-publishing,versioning}.md (add/add) - scripts/versioning/{New-Release,Show-VersionStatus,Update-Versions}.ps1 (modify/delete -- dev deleted them off the retired flow; kept deleted)
|
Important Review skippedToo many files! This PR contains 300 files, which is 150 over the limit of 150. To get a review, narrow the scope: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (300)
You can disable this status message by setting the Use the checkbox below for a quick retry:
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Analysis CompleteGenerated ECC bundle from 100 commits | Confidence: 85% View Pull Request #91Repository Profile
Changed Files (300)
Top hotspots
Top directories
Analysis Depth Readiness (deep-ready, 86%)ECC Tools uses this to decide whether recommendations should stay at commit-history/setup guidance or expand into CI, security, harness, reference-set, AI-routing, and team backlog work.
Reference Set Readiness (3/7, 43%)
Likely Future Issues (6)
Suggested Follow-up Work (6)
Copy-ready bodies test: add regression coverage for .claude/plan/partition-honor-investigation.js + scripts/docs-lint.ps1 ## Summary
- Add regression coverage for the recently touched code paths before more changes stack on top.
## Why
- Backfill regression coverage before another change set lands on the touched code paths.
## Touched paths
- `.claude/plan/partition-honor-investigation.js`
- `scripts/docs-lint.ps1`
## Validation
- Add or extend focused tests that exercise the touched paths.
- Run the affected test suite and verify the new coverage closes the gap.chore: sync config templates for .claude/settings.json ## Summary
- Update the example env files, sample configs, or deployment templates that should mirror the changed runtime configuration surface.
## Why
- Backfill example env files or config templates before a fresh setup drifts from the shipped runtime surface.
## Touched paths
- `.claude/settings.json`
## Validation
- Update the repo example env file or config template that should reflect the new runtime settings.
- Run the setup, boot, or deployment validation flow that depends on the changed config surface.analysis: add reference-set evidence for .claude/plan/partition-honor-investigation.js + .claude/settings.json ## Summary
- Add reference-set or eval evidence for the recently changed AI, analyzer, skill, agent, command, or harness guidance surface.
## Why
- Backfill eval, golden trace, benchmark, or reference-set evidence before another AI or harness-analysis change lands on the touched surface.
## Touched paths
- `.claude/plan/partition-honor-investigation.js`
- `.claude/settings.json`
## Validation
- Add or update an eval, golden trace, benchmark, fixture, or reference-set artifact for the changed AI/harness behavior.
- Compare the changed behavior against the maintained reference set and record the pass/fail evidence.
- Confirm the follow-up evidence covers the same analyzer, skill, agent, command, or harness surface touched by this PR.analysis: add RAG/evaluator evidence for docs/guides/embedding-best-practices.md ## Summary
- Add RAG/evaluator comparison evidence for the recently changed retrieval, ranking, embedding, or evaluator surface.
## Why
- Backfill reference-set comparison, golden trace, benchmark, or eval-run evidence before another RAG or evaluator change lands on the touched surface.
## Touched paths
- `docs/guides/embedding-best-practices.md`
## Validation
- Add or update an eval, reference set, golden trace, benchmark, fixture, or judge/scoring regression for the changed RAG/evaluator behavior.
- Compare the changed behavior against representative retrieval or evaluator cases and record pass/fail evidence.
- Confirm the follow-up evidence covers the same retrieval, embedding, ranking, or evaluator path touched by this PR.ci: add failure-mode evidence for .github/workflows/release-on-main.yml ## Summary
- Add CI failure-mode evidence for the recently changed workflow or test-runner surface.
## Why
- Backfill CI failure-mode evidence before another workflow or test-runner change lands on the touched surface.
## Touched paths
- `.github/workflows/release-on-main.yml`
## Validation
- Add or update a CI failure fixture, captured failing log, troubleshooting note, workflow dry-run evidence, or regression test for the changed CI/test-runner behavior.
- Run the affected workflow or test-runner entrypoint locally or in CI and record pass/fail evidence.chore: refresh lockfile and validate CI after dependency updates ## Summary
- Refresh the lockfile and rerun CI after the dependency or workflow changes in this PR.
## Why
- Package or workflow changes without a lockfile refresh tend to turn into noisy follow-up fixes after merge.
## Touched paths
- `.github/workflows/release-on-main.yml`
## Validation
- Refresh the lockfile in the same package manager used by the repo.
- Run the repo typecheck / test / CI entrypoints that depend on the updated package graph.Detected Workflows (9)
Generated Instincts (29)
After merging, import with: Files
|
Title:
Why
What changed
Checklist (required)
Docs touchpoints (if applicable)
Validation notes
References