Stanley Druckenmiller's obviously AI-written Wall Street Journal op-ed sparked a fierce debate about disclosure, plagiarism, and whether the tool used matters more than the thinking behind it. NLW lays out five rules for AI writing, including why the purity test will fade but the quality test never will, and why perceived laziness undermines the argument itself. Also covered: a practical crib sheet for emails, meeting notes, strategy memos, social copy, marketing, and op-eds.
The AI Daily Brief helps you understand the most important news and discussions in AI.
Subscribe to the podcast version of The AI Daily Brief wherever you listen: https://pod.link/1680633614
Get it ad free at http://patreon.com/aidailybrief
Learn more about the show https://aidailybrief.ai/
In this episode, Andy sits down with Dr. Jeremy Pollack, a social-organizational psychologist and founder of Pollack Peacebuilding Systems, author of Wired for Peace: Using 7 Neuroscience-Based Principles to Resolve Conflicts. Jeremy looks at conflict through the lens of the brain and nervous system, which helps explain why disagreements escalate so quickly and why the fixes we reach for often make things worse.
Andy and Jeremy talk about why de-escalation has to come before problem-solving, since solutions and stress do not mix. Jeremy walks us through his Sapien Model of six basic psychological needs, giving us a far more useful lens than labeling a stakeholder difficult, defensive, or resistant. You will hear how memory and prediction shape the way we read the person in front of us, what a team learns when its leader consistently avoids conflict, and why changing our experience of conflict requires new experiences, not just new beliefs. Jeremy also shares how this shows up at home, in marriage and parenting.
If you're looking for a practical, evidence-based way to handle the conflicts that come with leading, this episode is for you!
You can learn more about Jeremy and his work at CoachJeremyPollack.com.
For more learning on this topic, check out:
You can chat directly with PMeLa, the podcast's AI persona, to get episode recommendations and answers to your project management and leadership questions. Visit PeopleAndProjectsPodcast.com/PMeLa to chat with her.
I know you want to be a more confident leaderβthat's why you listen to this podcast. LEAD52 is a global community of people like you who are committed to transforming their ability to lead and deliver. It's 52 weeks of leadership learning, delivered right to your inbox, taking less than 5 minutes a week. And it's all for free. Learn more and sign up at GetLEAD52.com. Thanks!
Thank you for joining me for this episode of The People and Projects Podcast!
Talent Triangle: Power Skills
Topics: Leadership, Project Management, Conflict Resolution, Neuroscience, De-escalation, Psychological Safety, Emotional Regulation, Memory, Stakeholder Management, Team Culture, Accountability, Parenting
The following music was used for this episode:
Music: On Point by Steven O'Brien
License (CC BY 4.0): https://filmmusic.io/standard-license
Music: Energetic Drive Indie Rock by WinnieTheMoog
License (CC BY 4.0): https://filmmusic.io/standard-license
After our recent discussions on why FutureBuilder and StreamBuilder are architectural anti-patterns when placed inside Flutter widget trees, I started thinking: how can we make it even easierβeven completely mechanicalβto convert from a FutureBuilder or StreamBuilder to a BlocSignalBuilder?
Every Flutter developer knows the history. Years ago, I recorded a video breaking down the hidden traps of placing asynchronous builders in UI views: Why you shouldn't put FutureBuilder in your build method. Even the original official Flutter video on FutureBuilder initially instantiated the network future directly inside the build() method, until I filed an issue to get it corrected (which is why the official Flutter YouTube video still proudly bears "Take 2" on its clapperboard!).
The fundamental issue has never been that developers want bad architecture. The issue was friction.
FutureBuilder was simply the path of least resistance. To do it "properly" in traditional state management, developers had to create an entire BLoC or Cubit, declare separate Event and State classes (or union types), write boilerplate event handlers, wire asynchronous repository methods, manage subscription lifecycles, and inject everything into the widget tree.
With bloc_signals 1.1.0, that friction disappears completely.
We have introduced universal, symmetrical adapter extensions that allow any Dart Future, Stream, ReadonlySignal, or lifted primitive (value.$) to adapt into a synchronous BlocSignalBase container with a single method call.
When bridging asynchronous sources into synchronous state management, developers typically have one of two distinct intents:
T): You want raw domain objects (for example int, UserProfile, ThemeMode) with zero wrapper ceremony, and you have an immediate default or fallback value for frame 0.AsyncState<T>): You want first-class lifecycle tracking (AsyncLoading β AsyncData or AsyncError) with exhaustive pattern matching.To make the API completely intuitive and predictable, BlocSignal adheres to the Universal Dual-Track Principle:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β BlocSignal Universal Adapter Matrix β
βββββββββββββββββββββββββββββββββ¬βββββββββββββββββββββββββββββββββββββββββ€
β Method β Resulting Container Type β
βββββββββββββββββββββββββββββββββΌβββββββββββββββββββββββββββββββββββββββββ€
β .toBlocSignal(...) β BlocSignalBase<T> (Raw domain state) β
β .toAsyncBlocSignal(...) β BlocSignalBase<AsyncState<T>> (Async) β
βββββββββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββββββββββββββββ
Let us examine how each track works.
.toBlocSignal)
The .toBlocSignal(...) family strictly yields a BlocSignalBase<T> holding raw values of type T.
ReadonlySignal<T> & Lifted Primitives
Because signals in the signals_core graph always hold an immediate synchronous value, converting any signal to a BlocSignalBase requires no arguments:
// 1. Raw Signal -> BlocSignalBase<int>
final countSignal = signal(0);
final countBloc = countSignal.toBlocSignal();
// 2. Computed Expression -> BlocSignalBase<bool>
final isValidSignal = computed(() => username().isNotEmpty && password().length >= 8);
final authBloc = isValidSignal.toBlocSignal();
// 3. Lifted Primitive -> BlocSignalBase<double>
final priceBloc = 49.99.$.toBlocSignal();
The resulting SignalBlocSignal<T> subscribes directly to the underlying signal graph and emits synchronous state transitions whenever the source signal mutates. Calling close() on the container automatically unsubscribes the effect.
Future<T> with a Required Initial State
Futures do not have a synchronous value on frame 0. Therefore, when requesting raw domain values of type T, Future.toBlocSignal() requires an explicit initialState::
// Future<User> -> BlocSignalBase<User>
final userBloc = api.fetchUserProfile(userId).toBlocSignal(
initialState: User.anonymous(),
);
On frame 0, userBloc.stateValue is immediately User.anonymous(). As soon as the future completes, it emits the resolved User synchronously into the state machine. If the future throws, the error is routed safely to onError() and the container's registered BlocObserver.
Stream<T> with a Required Initial State
Similarly, any multi-value Stream<T> (such as a WebSocket, sensor stream, or legacy BLoC/Redux stream) adapts with a required initial value:
// Stream<int> -> BlocSignalBase<int>
final counterBloc = myStream.toBlocSignal(initialState: 0);
// Redux Store -> BlocSignalBase<AppState>
final reduxBloc = store.onChange.toBlocSignal(
initialState: store.state,
);
.toAsyncBlocSignal)
When you do not have an initial fallback value and want first-class loading, data, and error states, .toAsyncBlocSignal() converts Future<T> and Stream<T> into a BlocSignalBase<AsyncState<T>>.
// 1. Future<UserProfile> -> BlocSignalBase<AsyncState<UserProfile>>
final userProfileBloc = api.fetchUserProfile(userId).toAsyncBlocSignal();
// 2. Stream<List<ChatMessage>> -> BlocSignalBase<AsyncState<List<ChatMessage>>>
final chatBloc = chatSocket.messageStream.toAsyncBlocSignal();
The state lifecycle is completely automatic:
AsyncLoading().AsyncData(value).AsyncError(error, stackTrace).Think for a moment about how Flutter applications traditionally handled an asynchronous resource with a fallback default. You often had to write 30+ lines of fragile singleton and ChangeNotifier plumbing:
// π© The old way: Fragile singleton boilerplate with mutable async init
class UserManager extends ChangeNotifier {
UserManager._() { _init(); }
static final instance = UserManager._();
User _user = User.anonymous();
User get user => _user;
bool _loading = true;
Future<void> _init() async {
try {
_user = await api.fetchUser();
} finally {
_loading = false;
notifyListeners();
}
}
}
Compare that ceremony with BlocSignal:
// πͺ The BlocSignal way: 1 declarative expression
final userBloc = api.fetchUserProfile(userId).toBlocSignal(
initialState: User.anonymous(),
);
Even better: it is inherently lazy.
Because top-level variables and late fields in Dart are evaluated on demand:
void main(). If the user never navigates to that screen or feature, the network request is never fired and no resources are wasted..toAsyncBlocSignal(), the underlying FutureSignal defaults to lazy: true, meaning evaluation only triggers when an active UI consumer or test actually reads the signal.async main() Initialization Bottlenecks: You no longer need to stall app startup with await initAllServices() before runApp(). Features initialize on demand on the exact frame they are requested.What if userId is dynamic (for example derived from an auth session, a route parameter, or a dropdown selection)?
You can wire it directly into the reactive dependency graph:
// 1. Upstream reactive dependency:
final selectedUserId = signal<String>('42');
// 2. Downstream async pipeline β automatically refetches when selectedUserId changes:
final userProfileBloc = futureSignal(
() => api.fetchUserProfile(selectedUserId()),
).toBlocSignal();
When selectedUserId.value = '99' changes anywhere in your app, the futureSignal automatically detects the dependency change, refetches the profile, and emits state transitions through userProfileBloc directly into your BlocSignalBuilderβwith zero manual listeners, zero event dispatch plumbing, and zero didUpdateWidget lifecycle gymnastics.
FutureBuilder
Let us take a real-world example of FutureBuilder and see how clean and non-scary it is to replace it.
FutureBuilder)
Here is the classic code that lives in thousands of Flutter codebases:
// β ANTI-PATTERN: Trapping async I/O inside the widget tree
class UserProfilePage extends StatelessWidget {
const UserProfilePage({super.key, required this.userId});
final String userId;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('User Profile')),
body: FutureBuilder<UserProfile>(
// β οΈ DANGER: Re-invoked on every parent rebuild!
future: apiClient.fetchUserProfile(userId),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(child: Text('Error: ${snapshot.error}'));
}
if (snapshot.hasData) {
final user = snapshot.data!;
return ProfileView(user: user);
}
return const SizedBox.shrink();
},
),
);
}
}
Instead of wrapping the view in complex provider nesting, we simply pass the adapted container directly into our view widget via constructor parameters (clean prop-drilling):
// 1. At the route boundary, controller, or parent widget:
final userProfileBloc = apiClient.fetchUserProfile(userId).toAsyncBlocSignal();
// 2. Pass it directly to the view:
UserProfilePage(userProfileBloc: userProfileBloc);
Our presentation widget becomes a pure, lightweight StatelessWidget:
// β
BLOCSIGNAL PATTERN: Clean, synchronous projection of state
class UserProfilePage extends StatelessWidget {
const UserProfilePage({
super.key,
required this.userProfileBloc,
});
final BlocSignalBase<AsyncState<UserProfile>> userProfileBloc;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('User Profile')),
body: BlocSignalBuilder(
bloc: userProfileBloc,
builder: (context, state) => switch (state) {
AsyncData(:final value) => ProfileView(user: value),
AsyncLoading() => const Center(child: CircularProgressIndicator()),
AsyncError(:final error) => Center(child: Text('Error: $error')),
},
),
);
}
}
Look at how clear that is!
There are no nested InheritedWidget provider trees or noisy generic boilerplate. Type inference handles the builder automatically.
Note on Dependency Injection: Because
BlocSignalcontainers are pure Dart objects with zero framework baggage, you can supply them using whichever DI strategy fits your project: simple constructor prop-drilling (as shown above), top-level globals, service locators (such asGetIt),BlocSignalProvider, or Riverpod adapters.
build() re-runs synchronously without dispatching a new HTTP request.AsyncLoading, AsyncData, and AsyncError. No more forgetting edge cases or dealing with force unwraps (snapshot.data!).userProfileBloc with blocSignalTest in 0ms without mocking microtask timers or calling tester.pumpAndSettle().StreamBuilder
Now let us look at StreamBuilder.
StreamBuilder)
// β ANTI-PATTERN: Stream subscription lifecycle entangled with widget tree
class DeviceTemperatureWidget extends StatelessWidget {
const DeviceTemperatureWidget({super.key, required this.sensorService});
final SensorService sensorService;
@override
Widget build(BuildContext context) {
return StreamBuilder<double>(
stream: sensorService.temperatureStream,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Text('Reading sensor...');
}
return Text('${snapshot.data!.toStringAsFixed(1)}Β°C');
},
);
}
}
.toBlocSignal()
If you have a sensible initial value (for example 0.0), adapt the stream directly to a raw domain container and pass it straight into your widget:
// β
OPTION A: Raw Domain State with explicit initial value
class DeviceTemperatureWidget extends StatelessWidget {
const DeviceTemperatureWidget({
super.key,
required this.temperatureBloc,
});
final BlocSignalBase<double> temperatureBloc;
@override
Widget build(BuildContext context) {
return BlocSignalBuilder(
bloc: temperatureBloc,
builder: (context, temperature) {
return Text('${temperature.toStringAsFixed(1)}Β°C');
},
);
}
}
Or, if you prefer rich async lifecycle tracking:
// β
OPTION B: Rich Async Lifecycle State
class DeviceTemperatureWidget extends StatelessWidget {
const DeviceTemperatureWidget({
super.key,
required this.temperatureBloc,
});
final BlocSignalBase<AsyncState<double>> temperatureBloc;
@override
Widget build(BuildContext context) {
return BlocSignalBuilder(
bloc: temperatureBloc,
builder: (context, state) => switch (state) {
AsyncData(:final value) => Text('${value.toStringAsFixed(1)}Β°C'),
AsyncLoading() => const Text('Reading sensor...'),
AsyncError(:final error) => Text('Sensor offline: $error'),
},
);
}
}
Consider the difference in testability.
FutureBuilder Widget
// β οΈ Fragile, slow, timer-dependent
testWidgets('renders user profile', (tester) async {
await tester.pumpWidget(UserProfilePage(
userProfileBloc: Future.value(mockUser).toAsyncBlocSignal(),
));
// Instant synchronous verification of the initial loading state:
expect(find.byType(CircularProgressIndicator), findsOneWidget);
// Settle completion cleanly:
await tester.pump();
expect(find.text('Alice'), findsOneWidget);
});
BlocSignal Adapter Unit
Because BlocSignal operates synchronously with 0ms microtask delays, testing state transitions is declarative and instantaneous:
// β
Fast, synchronous, 100% deterministic
blocSignalTest<SignalBlocSignal<AsyncState<String>>, AsyncState<String>>(
'emits AsyncLoading then AsyncData on future completion',
build: () => Future.value('Alice').toAsyncBlocSignal(),
wait: const Duration(milliseconds: 10),
expect: () => [
isA<AsyncLoading<String>>(),
isA<AsyncData<String>>().having((s) => s.value, 'value', 'Alice'),
],
);
In modern application engineering, you will inevitably interact with diverse reactive abstractions:
Future<T>.Stream<T>.Signal<T> or Computed<T>.BlocSignal does not force you to rewrite your entire data layer or choose between the discipline of unidirectional data flow and the speed of fine-grained signals.
With .toBlocSignal() and .toAsyncBlocSignal(), every asynchronous stream, future, and signal in your architecture adapts seamlessly into a synchronous, predictable, 0ms reactive state machine.
Try out bloc_signals 1.1.0 today:
dependencies:
bloc_signals: ^1.1.0
bloc_signals_flutter: ^1.1.0
Happy coding!
Lore is a new source control system from Epic Games. It is designed for fast, distributed workflows, with local repositories that work offline and optional Lore servers when you need to collaborate.
Lore for Visual Studio brings that workflow directly into the IDE. It is also a practical example of what it takes to add a new source-control provider to Visual Studio: integrate onboarding, status, changes, commits, history, branches, authentication, and native diff and merge experiences into the places developers already use.
The extension lets you onboard a solution or folder, see file status in Solution Explorer, review changes, commit, manage branches, inspect history, and synchronize with a Lore server - all without dropping to a terminal.
Visual Studio already provides the integration points a source-control provider needs to participate in the everyday development workflow. Lore for Visual Studio uses them to surface repository status in Solution Explorer, provide commands in solution and file context menus, and offer dedicated Changes and History tool windows. Rather than making developers learn a separate workflow, the extension makes Lore available alongside the IDE experiences they already know.
Open a solution or folder and select Add to Source Control in the Visual Studio status bar. Choose Lore, then create a local repository.
Local repositories are fully offline. You can commit, create branches, switch branches, and browse history while all content remains on your machine. When you are ready to collaborate, create or connect to a Lore server and push your work.

You can also clone an existing Lore repository directly from Solution Explorer. The extension checks that the server is reachable, clones the working tree, and records the remote configuration so push and pull are ready immediately.

Once a solution is under Lore source control, status glyphs appear beside files in Solution Explorer. They refresh automatically as documents are saved, and the Lore Changes window provides a manual refresh command whenever you need one.
File context menus include the essentials:
.loreignoreMoves and renames performed in Solution Explorer are tracked automatically. The extension also uses Visual Studio's shared file-change service to detect changes made outside the IDE.
The Lore Changes window provides a dedicated commit experience modeled after Visual Studio's Git Changes window.

It presents changed files in a repository-root folder tree, including status badges for modified, added, deleted, renamed, and copied files.
You can select exactly which files belong in the next commit. Folder checkboxes are tri-state, the header checkbox selects everything at once, and your selection survives automatic refreshes while you write a commit message.
From the window, you can:
The Lore History tool window shows a read-only log for the repository associated with the open solution or folder.
History is paged, newest first, so even repositories with thousands of revisions remain responsive. Each revision shows its message, short hash, author, and local commit time. Select a revision to load only the files that it changed, then double-click a file to compare it with its direct parent in Visual Studio's native diff viewer.
The window stays in sync with the workspace and refreshes automatically after relevant Lore operations, such as commits, pulls, branch changes, and merges.
The branch picker in the Lore Changes window lets you switch branches, create a branch from the current revision, and merge another branch into the one you are working on.
Lore is offline-first. When the needed content is already cached locally, switching and merging do not require a network round trip. If content has been evicted from the local cache, Lore fetches it from the configured server and clearly reports when the server is unavailable.
When a merge conflicts, Visual Studio's built-in three-way merge experience opens for each conflicted file. Resolve the conflicts, accept the results, and Lore completes the merge commit.
There is no separate sign-in command. If a server-backed operation such as cloning, pushing, or pulling requires authentication, Lore asks whether to sign in and opens the default browser. After sign-in completes, the original operation is retried.
That keeps the experience simple: work locally when you can, authenticate only when a server operation actually needs it.
Lore for Visual Studio is available from the Visual Studio Marketplace.
The extension is open source, and contributions are welcome on GitHub. If you are building a source-control integration of your own, the project is also an example of how a provider can fit into Visual Studio's existing source-control workflow.