Darkwood · PHP · agents · Flow
The question
Not rhetorical. An engineering experiment.
The experiment · content/thanks-agent
Value +25
Value +40
Value +30
Value +20
Value +15
Value +0
+ SummaryAgent (+15) after fan-in
ThanksAgent
return [
'output' => 'Thanks.', // or Looks good. / Good job.
'tokens' => 2,
'messages' => 28,
'didWork' => false, // value forced to 0
];
Thesis
The scheduler cannot distinguish
productive work from performative work.
Cost is plural
WIP / MaxIpStrategy
Simulated in demo
Chatty acknowledgements
Prompt / index slices
Observability volume
Decision queue
Flow today · PHP ≥ 8.5
flowchart LR IP[Ip] --> Job[Job] Job --> Driver[Driver] Driver --> Events[PUSH PULL POP ASYNC] Events --> Job
Many IPs in flight ≠ graph joins.
Scatter / gather · demo pattern
flowchart LR Ips[Multiple Ips] --> Stage[ExecuteAgentJob] Stage --> Store[RunStore] Store --> Summary[SummaryAgent] Summary --> Report[Scoreboard]
MaxIpStrategy caps concurrency · fan-in is application state
Scoreboard · FiberDriver · PHP 8.5.4
Value 145
Cost 0.012
Messages 19
Events 5/5/5/5
Value 145
Cost 0.022 · +0.010
Messages 48 · +29
Events 6/6/6/6
Useful output unchanged. Resources up.
Economics
Looks tiny on the invoice line
Thanks → tends to ∞
Cheap useless work is not cheap.
It is subsidized noise.
Bottleneck moves
Calls you can fire
IPs in flight
Open contexts
Reject / accept bandwidth
Stop counting running tasks.
Count decisions waiting. · SupervisionBudget
thanks-agent:bench-io · synthetic I/O · PHP 8.5.4
~600 ms · value 130
~167 ms · value 130
~179 ms · value 130
skipped on 8.5.4
~3.6× wall improvement. Same emptiness from Thanks.
Editorial callback
A better poller can execute
useless work faster.
Performance amplifies whatever
the system is optimizing.
Terminal lifecycle
flowchart TB Exec[Execute] --> Success[Success] Exec --> Failure[Failure] Exec --> Abandon[Abandon] Success --> Complete[CompleteEvent] Failure --> Error[ErrorEvent] Abandon --> Hole[Accounting hole] Complete --> Ledger[CostLedger] Error --> Ledger
Happy-path-only FinOps lies.
What changed in Flow
CostLedger · ValueTag
Complete / Error
SupervisionBudget
PollerInterface · Duration
Cancel · abandon terminal
True DAG joins
Decision-queue metrics
CodeMap · AgentRouter
Value and cost belong in the runtime vocabulary.
Closing
The harder problem is deciding
which work should exist at all.
The next optimization is not another agent.
It is a better definition of value.