diff --git a/Directory.Build.props b/Directory.Build.props
index 6843c07..ad74752 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,17 +1,17 @@
+
+ enable
+ enable
+ true
+ true
+
+
+
LICENSE
-
- true
-
- true
- enable
- enable
-
-
diff --git a/Directory.Build.targets b/Directory.Build.targets
new file mode 100644
index 0000000..6d45f3a
--- /dev/null
+++ b/Directory.Build.targets
@@ -0,0 +1,8 @@
+
+
+
+ $(NoWarn);1591;CS1591
+ $(WarningsNotAsErrors);1591;CS1591
+
+
+
diff --git a/src/Coven.Agents.OpenAI/AgentMaxLengthWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentMaxLengthWindowPolicy.cs
index 3592d29..8bc12a6 100644
--- a/src/Coven.Agents.OpenAI/AgentMaxLengthWindowPolicy.cs
+++ b/src/Coven.Agents.OpenAI/AgentMaxLengthWindowPolicy.cs
@@ -10,14 +10,20 @@ public sealed class AgentMaxLengthWindowPolicy : IWindowPolicy
+ /// Creates a policy that emits when the total length of recent chunks reaches the maximum.
+ ///
+ /// Maximum total characters across the current window; must be greater than zero.
public AgentMaxLengthWindowPolicy(int max)
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0);
_max = max;
}
+ ///
public int MinChunkLookback => 1;
+ ///
public bool ShouldEmit(StreamWindow window)
{
int total = 0;
diff --git a/src/Coven.Agents.OpenAI/AgentParagraphWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentParagraphWindowPolicy.cs
index 44baef1..43f19a4 100644
--- a/src/Coven.Agents.OpenAI/AgentParagraphWindowPolicy.cs
+++ b/src/Coven.Agents.OpenAI/AgentParagraphWindowPolicy.cs
@@ -10,8 +10,10 @@ namespace Coven.Agents.OpenAI;
///
public sealed class AgentParagraphWindowPolicy : IWindowPolicy
{
+ ///
public int MinChunkLookback => 2;
+ ///
public bool ShouldEmit(StreamWindow window)
{
StringBuilder stringBuilder = new();
diff --git a/src/Coven.Agents.OpenAI/AgentThoughtMaxLengthWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtMaxLengthWindowPolicy.cs
index 0ec1aff..7c8fc13 100644
--- a/src/Coven.Agents.OpenAI/AgentThoughtMaxLengthWindowPolicy.cs
+++ b/src/Coven.Agents.OpenAI/AgentThoughtMaxLengthWindowPolicy.cs
@@ -10,14 +10,20 @@ public sealed class AgentThoughtMaxLengthWindowPolicy : IWindowPolicy
+ /// Creates a policy that emits when the total length of recent thought chunks reaches the maximum.
+ ///
+ /// Maximum total characters across the current thought window; must be greater than zero.
public AgentThoughtMaxLengthWindowPolicy(int max)
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0);
_max = max;
}
+ ///
public int MinChunkLookback => 1;
+ ///
public bool ShouldEmit(StreamWindow window)
{
int total = 0;
@@ -35,4 +41,3 @@ public bool ShouldEmit(StreamWindow window)
return false;
}
}
-
diff --git a/src/Coven.Agents.OpenAI/AgentThoughtParagraphWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtParagraphWindowPolicy.cs
index 480dfd7..9166152 100644
--- a/src/Coven.Agents.OpenAI/AgentThoughtParagraphWindowPolicy.cs
+++ b/src/Coven.Agents.OpenAI/AgentThoughtParagraphWindowPolicy.cs
@@ -10,8 +10,10 @@ namespace Coven.Agents.OpenAI;
///
public sealed class AgentThoughtParagraphWindowPolicy : IWindowPolicy
{
+ ///
public int MinChunkLookback => 2;
+ ///
public bool ShouldEmit(StreamWindow window)
{
StringBuilder stringBuilder = new();
@@ -32,4 +34,3 @@ public bool ShouldEmit(StreamWindow window)
return concatenatedWindow.EndsWith("\r\n\r\n", StringComparison.Ordinal) || concatenatedWindow.EndsWith("\n\n", StringComparison.Ordinal);
}
}
-
diff --git a/src/Coven.Agents.OpenAI/AgentThoughtSentenceWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtSentenceWindowPolicy.cs
index fe96807..06643e1 100644
--- a/src/Coven.Agents.OpenAI/AgentThoughtSentenceWindowPolicy.cs
+++ b/src/Coven.Agents.OpenAI/AgentThoughtSentenceWindowPolicy.cs
@@ -11,8 +11,10 @@ namespace Coven.Agents.OpenAI;
public sealed class AgentThoughtSentenceWindowPolicy : IWindowPolicy
{
// 4 chunks should be generous for windowing sentence termination
+ ///
public int MinChunkLookback => 4;
+ ///
public bool ShouldEmit(StreamWindow window)
{
StringBuilder sb = new();
@@ -44,4 +46,3 @@ private static bool EndsWithSentenceBoundary(StringBuilder sb)
return c is '.' or '!' or '?';
}
}
-
diff --git a/src/Coven.Agents.OpenAI/AgentThoughtSummaryMarkerWindowPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtSummaryMarkerWindowPolicy.cs
index 7db789a..79529f6 100644
--- a/src/Coven.Agents.OpenAI/AgentThoughtSummaryMarkerWindowPolicy.cs
+++ b/src/Coven.Agents.OpenAI/AgentThoughtSummaryMarkerWindowPolicy.cs
@@ -11,8 +11,10 @@ namespace Coven.Agents.OpenAI;
///
public sealed class AgentThoughtSummaryMarkerWindowPolicy : IWindowPolicy
{
+ ///
public int MinChunkLookback => 10;
+ ///
public bool ShouldEmit(StreamWindow window)
{
StringBuilder stringBuilder = new();
diff --git a/src/Coven.Agents.OpenAI/AgentThoughtSummaryShatterPolicy.cs b/src/Coven.Agents.OpenAI/AgentThoughtSummaryShatterPolicy.cs
index 70fe1f8..c5d0249 100644
--- a/src/Coven.Agents.OpenAI/AgentThoughtSummaryShatterPolicy.cs
+++ b/src/Coven.Agents.OpenAI/AgentThoughtSummaryShatterPolicy.cs
@@ -24,6 +24,14 @@ private static class Grammar
public static readonly string[] _paragraphBoundaries = ["\r\n\r\n", "\n\n", "\r\n"];
}
+ ///
+ /// Splits an into up to two entries at the first detected summary marker boundary.
+ ///
+ /// The source agent entry.
+ ///
+ /// Zero or more instances: at most two parts
+ /// when a boundary is present; otherwise no output.
+ ///
public IEnumerable Shatter(AgentEntry entry)
{
if (entry is not AgentThought thought || string.IsNullOrEmpty(thought.Text))
diff --git a/src/Coven.Agents.OpenAI/Coven.Agents.OpenAI.csproj b/src/Coven.Agents.OpenAI/Coven.Agents.OpenAI.csproj
index 71a852e..c7d8815 100644
--- a/src/Coven.Agents.OpenAI/Coven.Agents.OpenAI.csproj
+++ b/src/Coven.Agents.OpenAI/Coven.Agents.OpenAI.csproj
@@ -1,6 +1,12 @@
net10.0
+ true
+ true
+ $(MSBuildProjectName)
+ OpenAI agent integration for Coven.
+ Coven
+ coven;agents;openai;llm;integration
diff --git a/src/Coven.Agents.OpenAI/ReasoningEffort.cs b/src/Coven.Agents.OpenAI/ReasoningEffort.cs
index ccb4601..0d57325 100644
--- a/src/Coven.Agents.OpenAI/ReasoningEffort.cs
+++ b/src/Coven.Agents.OpenAI/ReasoningEffort.cs
@@ -8,8 +8,10 @@ namespace Coven.Agents.OpenAI;
///
public enum ReasoningEffort
{
+ /// Minimal additional compute for reasoning.
Low,
+ /// Balanced additional compute for reasoning.
Medium,
+ /// Maximum additional compute for reasoning.
High
}
-
diff --git a/src/Coven.Agents/Coven.Agents.csproj b/src/Coven.Agents/Coven.Agents.csproj
index a9fe0f8..c369201 100644
--- a/src/Coven.Agents/Coven.Agents.csproj
+++ b/src/Coven.Agents/Coven.Agents.csproj
@@ -1,6 +1,12 @@
net10.0
+ true
+ true
+ $(MSBuildProjectName)
+ Agent abstractions and helpers for Coven.
+ Coven
+ coven;agents;abstractions
diff --git a/src/Coven.Chat.Console/Coven.Chat.Console.csproj b/src/Coven.Chat.Console/Coven.Chat.Console.csproj
index bb5ad95..d7b20f2 100644
--- a/src/Coven.Chat.Console/Coven.Chat.Console.csproj
+++ b/src/Coven.Chat.Console/Coven.Chat.Console.csproj
@@ -2,6 +2,12 @@
net10.0
+ true
+ true
+ $(MSBuildProjectName)
+ Console chat adapter for Coven (stdin/stdout).
+ Coven
+ coven;agents;chat;console;adapter
@@ -12,4 +18,3 @@
-
diff --git a/src/Coven.Chat.Discord/Coven.Chat.Discord.csproj b/src/Coven.Chat.Discord/Coven.Chat.Discord.csproj
index de87879..91b85b6 100644
--- a/src/Coven.Chat.Discord/Coven.Chat.Discord.csproj
+++ b/src/Coven.Chat.Discord/Coven.Chat.Discord.csproj
@@ -2,6 +2,12 @@
net10.0
+ true
+ true
+ $(MSBuildProjectName)
+ Discord chat adapter for Coven using Discord.Net.
+ Coven
+ coven;agents;chat;discord;adapter
diff --git a/src/Coven.Chat.Discord/DiscordScrivener.cs b/src/Coven.Chat.Discord/DiscordScrivener.cs
index a858338..38a4c13 100644
--- a/src/Coven.Chat.Discord/DiscordScrivener.cs
+++ b/src/Coven.Chat.Discord/DiscordScrivener.cs
@@ -11,10 +11,11 @@ internal sealed class DiscordScrivener : IScrivener
private readonly ILogger _logger;
///
- ///
+ /// Wraps a keyed inner scrivener and forwards outbound efferent messages to Discord.
///
- ///
- ///
+ /// The keyed inner used for storage.
+ /// The gateway connection for sending messages to Discord.
+ /// Logger for diagnostic breadcrumbs.
/// Because we are what we utilize, ensure that the inner scrivener is keyed in DI.
public DiscordScrivener([FromKeyedServices("Coven.InternalDiscordScrivener")] IScrivener scrivener, DiscordGatewayConnection discordClient, ILogger logger)
{
diff --git a/src/Coven.Chat.Discord/DiscordTransmuter.cs b/src/Coven.Chat.Discord/DiscordTransmuter.cs
index d8e509e..c9daa89 100644
--- a/src/Coven.Chat.Discord/DiscordTransmuter.cs
+++ b/src/Coven.Chat.Discord/DiscordTransmuter.cs
@@ -8,6 +8,12 @@ namespace Coven.Chat.Discord;
///
public class DiscordTransmuter : IBiDirectionalTransmuter
{
+ ///
+ /// Transmutes Discord-afferent entries into chat entries.
+ ///
+ /// The source Discord entry.
+ /// A cancellation token.
+ /// The mapped .
public Task TransmuteAfferent(DiscordEntry Input, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -20,6 +26,12 @@ public Task TransmuteAfferent(DiscordEntry Input, CancellationToken c
};
}
+ ///
+ /// Transmutes chat-efferent entries into Discord entries.
+ ///
+ /// The source chat entry.
+ /// A cancellation token.
+ /// The mapped .
public Task TransmuteEfferent(ChatEntry Output, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
diff --git a/src/Coven.Chat/Coven.Chat.csproj b/src/Coven.Chat/Coven.Chat.csproj
index 9571c58..cd6a2e7 100644
--- a/src/Coven.Chat/Coven.Chat.csproj
+++ b/src/Coven.Chat/Coven.Chat.csproj
@@ -1,6 +1,12 @@
net10.0
+ true
+ true
+ $(MSBuildProjectName)
+ Chat primitives and windowing integration for Coven.
+ Coven
+ coven;agents;chat;windowing;journal
diff --git a/src/Coven.Chat/Shattering/ChatChunkMaxLengthShatterPolicy.cs b/src/Coven.Chat/Shattering/ChatChunkMaxLengthShatterPolicy.cs
index b77bf1c..f499bab 100644
--- a/src/Coven.Chat/Shattering/ChatChunkMaxLengthShatterPolicy.cs
+++ b/src/Coven.Chat/Shattering/ChatChunkMaxLengthShatterPolicy.cs
@@ -4,19 +4,31 @@
namespace Coven.Chat.Shattering;
///
-/// Splits long chat text into <= max-length ChatChunk segments.
-/// Applies to ChatOutgoingDraft and ChatChunk; other entries are ignored.
+/// Splits long chat text into segments with length less than or equal to the configured maximum.
+/// Applies to and ; other entries are ignored.
///
public sealed class ChatChunkMaxLengthShatterPolicy : IShatterPolicy
{
private readonly int _max;
+ ///
+ /// Creates a new shatter policy.
+ ///
+ /// Maximum characters per emitted chunk. Must be greater than zero.
public ChatChunkMaxLengthShatterPolicy(int max)
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0);
_max = max;
}
+ ///
+ /// Splits supported entries into chunks not exceeding the configured maximum length.
+ ///
+ /// The input entry to consider.
+ ///
+ /// Zero or more instances representing the shattered output.
+ /// For unsupported entry types, yields nothing.
+ ///
public IEnumerable Shatter(ChatEntry entry)
{
switch (entry)
@@ -38,6 +50,9 @@ public IEnumerable Shatter(ChatEntry entry)
}
}
+ ///
+ /// Helper that splits raw text into fixed-size parts.
+ ///
private IEnumerable Split(string? text)
{
string s = text ?? string.Empty;
@@ -57,4 +72,3 @@ private IEnumerable Split(string? text)
}
}
}
-
diff --git a/src/Coven.Chat/Shattering/ChatParagraphShatterPolicy.cs b/src/Coven.Chat/Shattering/ChatParagraphShatterPolicy.cs
index b8c3d23..a68fcf3 100644
--- a/src/Coven.Chat/Shattering/ChatParagraphShatterPolicy.cs
+++ b/src/Coven.Chat/Shattering/ChatParagraphShatterPolicy.cs
@@ -14,6 +14,13 @@ namespace Coven.Chat.Shattering;
///
public sealed class ChatParagraphShatterPolicy : IShatterPolicy
{
+ ///
+ /// Splits supported draft entries into paragraph-sized segments.
+ ///
+ /// The entry to consider for shattering.
+ ///
+ /// Zero or more instances. For unsupported entry types, yields nothing.
+ ///
public IEnumerable Shatter(ChatEntry entry)
{
switch (entry)
diff --git a/src/Coven.Chat/Shattering/ChatSentenceShatterPolicy.cs b/src/Coven.Chat/Shattering/ChatSentenceShatterPolicy.cs
index da194d5..e9c5124 100644
--- a/src/Coven.Chat/Shattering/ChatSentenceShatterPolicy.cs
+++ b/src/Coven.Chat/Shattering/ChatSentenceShatterPolicy.cs
@@ -14,6 +14,13 @@ namespace Coven.Chat.Shattering;
///
public sealed class ChatSentenceShatterPolicy : IShatterPolicy
{
+ ///
+ /// Splits supported draft entries into sentence-sized segments.
+ ///
+ /// The entry to consider for shattering.
+ ///
+ /// Zero or more instances. For unsupported entry types, yields nothing.
+ ///
public IEnumerable Shatter(ChatEntry entry)
{
switch (entry)
diff --git a/src/Coven.Chat/Windowing/ChatMaxLengthWindowPolicy.cs b/src/Coven.Chat/Windowing/ChatMaxLengthWindowPolicy.cs
index 769058d..373c0b1 100644
--- a/src/Coven.Chat/Windowing/ChatMaxLengthWindowPolicy.cs
+++ b/src/Coven.Chat/Windowing/ChatMaxLengthWindowPolicy.cs
@@ -11,14 +11,20 @@ public sealed class ChatMaxLengthWindowPolicy : IWindowPolicy
{
private readonly int _max;
+ ///
+ /// Creates a policy that emits when the total length of recent chat chunks reaches the maximum.
+ ///
+ /// Maximum total characters across the current window; must be greater than zero.
public ChatMaxLengthWindowPolicy(int max)
{
ArgumentOutOfRangeException.ThrowIfLessThanOrEqual(max, 0);
_max = max;
}
+ ///
public int MinChunkLookback => int.MaxValue;
+ ///
public bool ShouldEmit(StreamWindow window)
{
int total = 0;
@@ -36,4 +42,3 @@ public bool ShouldEmit(StreamWindow window)
return false;
}
}
-
diff --git a/src/Coven.Chat/Windowing/ChatParagraphWindowPolicy.cs b/src/Coven.Chat/Windowing/ChatParagraphWindowPolicy.cs
index daf78a0..fff4e37 100644
--- a/src/Coven.Chat/Windowing/ChatParagraphWindowPolicy.cs
+++ b/src/Coven.Chat/Windowing/ChatParagraphWindowPolicy.cs
@@ -10,8 +10,10 @@ namespace Coven.Chat.Windowing;
///
public sealed class ChatParagraphWindowPolicy : IWindowPolicy
{
+ ///
public int MinChunkLookback => int.MaxValue;
+ ///
public bool ShouldEmit(StreamWindow window)
{
StringBuilder sb = new();
@@ -52,4 +54,3 @@ private static string TrimEndExceptNewlines(string s)
return end == s.Length ? s : s[..end];
}
}
-
diff --git a/src/Coven.Chat/Windowing/ChatSentenceWindowPolicy.cs b/src/Coven.Chat/Windowing/ChatSentenceWindowPolicy.cs
index 44688ad..593d307 100644
--- a/src/Coven.Chat/Windowing/ChatSentenceWindowPolicy.cs
+++ b/src/Coven.Chat/Windowing/ChatSentenceWindowPolicy.cs
@@ -11,8 +11,10 @@ namespace Coven.Chat.Windowing;
public sealed class ChatSentenceWindowPolicy : IWindowPolicy
{
// 4 chunks should be generous for windowing sentence termination
+ ///
public int MinChunkLookback => 4;
+ ///
public bool ShouldEmit(StreamWindow window)
{
StringBuilder sb = new();
@@ -46,4 +48,3 @@ private static bool EndsWithSentenceBoundary(StringBuilder sb)
return c is '.' or '!' or '?';
}
}
-
diff --git a/src/Coven.Core.Streaming/ChainedShatterPolicy.cs b/src/Coven.Core.Streaming/ChainedShatterPolicy.cs
index 9dff300..96fd030 100644
--- a/src/Coven.Core.Streaming/ChainedShatterPolicy.cs
+++ b/src/Coven.Core.Streaming/ChainedShatterPolicy.cs
@@ -14,6 +14,12 @@ public sealed class ChainedShatterPolicy(params IShatterPolicy[]
{
private readonly IShatterPolicy[] _policies = policies ?? [];
+ ///
+ /// Applies each shatter policy in order to the provided entry, forwarding
+ /// unchanged entries to subsequent policies and yielding only transformed outputs.
+ ///
+ /// The source entry to shatter.
+ /// Zero or more transformed entries produced by the chain.
public IEnumerable Shatter(TEntry entry)
{
if (_policies.Length == 0)
@@ -53,4 +59,3 @@ public IEnumerable Shatter(TEntry entry)
}
}
}
-
diff --git a/src/Coven.Core.Streaming/CompositeWindowPolicy.cs b/src/Coven.Core.Streaming/CompositeWindowPolicy.cs
index 5d71690..3fd450a 100644
--- a/src/Coven.Core.Streaming/CompositeWindowPolicy.cs
+++ b/src/Coven.Core.Streaming/CompositeWindowPolicy.cs
@@ -9,6 +9,12 @@ public sealed class CompositeWindowPolicy : IWindowPolicy
{
private readonly IReadOnlyList> _policies;
+ ///
+ /// Creates a composite policy that emits when any child policy emits.
+ /// Uses the maximum across children.
+ ///
+ /// One or more window policies to compose.
+ /// Thrown when no policies are provided.
public CompositeWindowPolicy(params IWindowPolicy[] policies)
{
if (policies is null || policies.Length == 0)
@@ -19,9 +25,10 @@ public CompositeWindowPolicy(params IWindowPolicy[] policies)
MinChunkLookback = _policies.Max(s => s.MinChunkLookback);
}
+ ///
public int MinChunkLookback { get; }
+ ///
public bool ShouldEmit(StreamWindow window)
=> _policies.Any(s => s.ShouldEmit(window));
}
-
diff --git a/src/Coven.Core.Streaming/Coven.Core.Streaming.csproj b/src/Coven.Core.Streaming/Coven.Core.Streaming.csproj
index e1ed8ae..34225b5 100644
--- a/src/Coven.Core.Streaming/Coven.Core.Streaming.csproj
+++ b/src/Coven.Core.Streaming/Coven.Core.Streaming.csproj
@@ -2,6 +2,12 @@
net10.0
+ true
+ true
+ $(MSBuildProjectName)
+ Streaming/windowing utilities and daemon for chunked message flows.
+ Coven
+ coven;agents;streaming;windowing;batching
diff --git a/src/Coven.Core.Streaming/LambdaShatterPolicy.cs b/src/Coven.Core.Streaming/LambdaShatterPolicy.cs
index f453f11..2556c30 100644
--- a/src/Coven.Core.Streaming/LambdaShatterPolicy.cs
+++ b/src/Coven.Core.Streaming/LambdaShatterPolicy.cs
@@ -1,11 +1,17 @@
// SPDX-License-Identifier: BUSL-1.1
namespace Coven.Core.Streaming;
+///
+/// Shatter policy backed by a provided delegate.
+///
+/// The entry type to shatter.
+/// Delegate that produces zero or more entries for a given input.
public sealed class LambdaShatterPolicy(Func> shatter)
: IShatterPolicy
{
private readonly Func> _shatter = shatter ?? throw new ArgumentNullException(nameof(shatter));
+ ///
public IEnumerable Shatter(TEntry entry)
=> _shatter(entry);
}
diff --git a/src/Coven.Core.Streaming/StreamWindow.cs b/src/Coven.Core.Streaming/StreamWindow.cs
index 0eb4892..1edd898 100644
--- a/src/Coven.Core.Streaming/StreamWindow.cs
+++ b/src/Coven.Core.Streaming/StreamWindow.cs
@@ -5,13 +5,13 @@ namespace Coven.Core.Streaming;
/// Snapshot of the current streaming window passed to window policies.
///
/// Chunk type under consideration.
+/// Recent chunks in the window (respecting MinChunkLookback semantics).
+/// Total number of chunks observed in the current buffer.
+/// Timestamp when windowing started.
+/// Timestamp of the last emit.
public readonly record struct StreamWindow(
-/// Recent chunks in the window (respecting MinChunkLookback semantics).
-IEnumerable PendingChunks,
-/// Total number of chunks observed in the current buffer.
-int ChunkCount,
-/// Timestamp when windowing started.
-DateTimeOffset StartedAt,
-/// Timestamp of the last emit.
-DateTimeOffset LastEmitAt
+ IEnumerable PendingChunks,
+ int ChunkCount,
+ DateTimeOffset StartedAt,
+ DateTimeOffset LastEmitAt
);
diff --git a/src/Coven.Core.Tests/Coven.Core.Tests.csproj b/src/Coven.Core.Tests/Coven.Core.Tests.csproj
index 32a27fe..483afce 100644
--- a/src/Coven.Core.Tests/Coven.Core.Tests.csproj
+++ b/src/Coven.Core.Tests/Coven.Core.Tests.csproj
@@ -4,6 +4,7 @@
net10.0
false
true
+ true
diff --git a/src/Coven.Core/Coven.Core.csproj b/src/Coven.Core/Coven.Core.csproj
index b3eb815..5f67fc7 100644
--- a/src/Coven.Core/Coven.Core.csproj
+++ b/src/Coven.Core/Coven.Core.csproj
@@ -1,17 +1,16 @@
-
net10.0
-
-
+ true
+ true
+ $(MSBuildProjectName)
+ Coven core runtime: MagikBlocks, builder, routing, journaling.
+ Coven
+ coven;agents;orchestration;runtime;routing;journal
+
-
-
-
-
-
diff --git a/src/Coven.Core/GetWorkRequest.cs b/src/Coven.Core/GetWorkRequest.cs
index 8ce82fe..130a970 100644
--- a/src/Coven.Core/GetWorkRequest.cs
+++ b/src/Coven.Core/GetWorkRequest.cs
@@ -2,7 +2,15 @@
namespace Coven.Core;
-// A request to advance one unit of work in Pull mode.
+///
+/// A single-step work request used in pull mode.
+/// One instance is provided each time the work increment advances.
+///
+/// Type of the current input value.
+/// The current value to process for this step.
+/// Optional tags that influence selection for this step.
+/// Optional branch identifier to isolate tag state.
+/// Cancellation token propagated from the orchestrator.
public sealed record GetWorkRequest
(
TIn Input,
diff --git a/src/Coven.Core/IScrivener.cs b/src/Coven.Core/IScrivener.cs
index 652e5f2..107c58d 100644
--- a/src/Coven.Core/IScrivener.cs
+++ b/src/Coven.Core/IScrivener.cs
@@ -52,6 +52,7 @@ public interface IScrivener where TJournalEntryType : notnull
///
/// The derived entry type to match.
/// Only consider entries strictly after this position.
+ /// Predicate to select the desired derived entry.
/// A cancellation token.
/// The first matching (journalPosition, entry) pair with the derived entry.
Task<(long journalPosition, TDerived entry)> WaitForAsync(long afterPosition, Func match, CancellationToken cancellationToken = default)
diff --git a/src/Coven.Core/InMemoryScrivener.cs b/src/Coven.Core/InMemoryScrivener.cs
index f4d35a2..df1624c 100644
--- a/src/Coven.Core/InMemoryScrivener.cs
+++ b/src/Coven.Core/InMemoryScrivener.cs
@@ -5,7 +5,7 @@
namespace Coven.Core;
///
-/// In-memory implementation of IScrivener journal with simple, single-process semantics;
+/// In-memory implementation of with simple, single-process semantics;
/// supports tailing, backward read, and predicate waits.
///
/// The journal entry type.
diff --git a/src/Coven.Core/Routing/BlockInvokerFactory.cs b/src/Coven.Core/Routing/BlockInvokerFactory.cs
index 7a5013f..b7c918d 100644
--- a/src/Coven.Core/Routing/BlockInvokerFactory.cs
+++ b/src/Coven.Core/Routing/BlockInvokerFactory.cs
@@ -23,7 +23,7 @@ public static Func
-
diff --git a/src/toys/Coven.Toys.ConsoleOpenAI/Coven.Toys.ConsoleOpenAI.csproj b/src/toys/Coven.Toys.ConsoleOpenAI/Coven.Toys.ConsoleOpenAI.csproj
index e19ffd6..5ead2a2 100644
--- a/src/toys/Coven.Toys.ConsoleOpenAI/Coven.Toys.ConsoleOpenAI.csproj
+++ b/src/toys/Coven.Toys.ConsoleOpenAI/Coven.Toys.ConsoleOpenAI.csproj
@@ -3,6 +3,7 @@
Exe
net10.0
+ false
@@ -15,4 +16,3 @@
-
diff --git a/src/toys/Coven.Toys.ConsoleOpenAIStreaming/Coven.Toys.ConsoleOpenAIStreaming.csproj b/src/toys/Coven.Toys.ConsoleOpenAIStreaming/Coven.Toys.ConsoleOpenAIStreaming.csproj
index e19ffd6..5ead2a2 100644
--- a/src/toys/Coven.Toys.ConsoleOpenAIStreaming/Coven.Toys.ConsoleOpenAIStreaming.csproj
+++ b/src/toys/Coven.Toys.ConsoleOpenAIStreaming/Coven.Toys.ConsoleOpenAIStreaming.csproj
@@ -3,6 +3,7 @@
Exe
net10.0
+ false
@@ -15,4 +16,3 @@
-
diff --git a/src/toys/Coven.Toys.DiscordChat/Coven.Toys.DiscordChat.csproj b/src/toys/Coven.Toys.DiscordChat/Coven.Toys.DiscordChat.csproj
index 85f92b0..e74d33b 100644
--- a/src/toys/Coven.Toys.DiscordChat/Coven.Toys.DiscordChat.csproj
+++ b/src/toys/Coven.Toys.DiscordChat/Coven.Toys.DiscordChat.csproj
@@ -1,9 +1,10 @@
-
- Exe
- net10.0
-
+
+ Exe
+ net10.0
+ false
+
diff --git a/src/toys/Coven.Toys.DiscordStreaming/Coven.Toys.DiscordStreaming.csproj b/src/toys/Coven.Toys.DiscordStreaming/Coven.Toys.DiscordStreaming.csproj
index d40d5d8..0bde137 100644
--- a/src/toys/Coven.Toys.DiscordStreaming/Coven.Toys.DiscordStreaming.csproj
+++ b/src/toys/Coven.Toys.DiscordStreaming/Coven.Toys.DiscordStreaming.csproj
@@ -2,6 +2,7 @@
Exe
net10.0
+ false
@@ -12,4 +13,3 @@
-