Stack 1/5: Foundations — repair, Zeitwerk, durable journal, orchestrator composition (rounds 1-4)#1
Conversation
The CLI spec invoked 'agent create' without the required --purpose
option, causing Thor to exit(1) mid-suite and silently truncate the
run at 65 of 474 examples. Repairing that revealed 12 latent failures:
- CLI 'agent create' used Agent.new with a block that initialize never
yields, silently discarding role/purpose; now uses Agent.build
- PersistentAgentStore#store never assigned generated IDs back to the
agent, so re-storing an agent duplicated it instead of versioning it
- PersistentAgentStore#list_all now accepts both the documented
all(filter: {...}) form (ADR-015) and the bare all(capability: ...)
- Agentic.register_capability/.assemble_agent now use the public
readers instead of module ivars
- AgentAssemblyEngine keyword inference now stem-matches capability
names ('Analyze the data' matches data_analysis), compounds
importance across sources, and lets explicit input capabilities
raise importance over weaker keyword matches
- ExecutionObserver#display_progress prints the newline that ends the
carriage-return progress line when all tasks complete
- Align LLM strategy specs with the implemented fallback design and
replace unsupported expect_any_instance_of + have_received
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Documents the multi-perspective review of the codebase (Matz, DHH, tenderlove, fxn, ioquatix, Jeremy Evans, solnic, Mike Perham, Sandi Metz, ankane), the synthesis of what they agree on, and the prologue field notes on the truncated test suite discovered before the builds. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Remove all require_relative calls for Zeitwerk-managed constants (nine in lib/agentic.rb plus the rest scattered through lib/), add the missing 'ui' => 'UI' inflection that the manual requires had been masking, and require thor from each CLI file that reopens class CLI < Thor so the directory is loadable file-by-file. The CLI (and its Thor/tty-* dependency stack) is no longer eagerly loaded by the library entrypoint; exe/agentic reaches Agentic::CLI through a normal autoload. Measured: require 'agentic' drops from ~272ms to ~14ms and from 612 to 186 loaded features. Part of the Rubyist-perspectives build series (Xavier Noria persona); field notes in docs/perspectives/field-notes/04-fxn.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A no-network, no-API-key example showing an agent, a lambda-backed capability, and a result on one screen. Field notes in docs/perspectives/field-notes/01-matz.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Agentic.run(goal, model:, concurrency:) compresses the planner -> task definitions -> orchestrator -> provider pipeline into the single method most library users actually want, mirroring what the CLI's execute_plan_immediately already did internally. Part of the Rubyist-perspectives build series (DHH persona); field notes in docs/perspectives/field-notes/02-dhh.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
benchmark/boot.rb measures wall time, allocations, and loaded-file count for requiring the library, autoloading the CLI, and initializing agent assembly - each in a fresh subprocess. Agentic.initialize_agent_assembly previously memoized global state with a bare nil check; concurrent callers could each build their own PersistentAgentStore against the same index file. It now uses a mutex with a double-checked re-entry, and assigns the flag ivar last so lock-skipping readers never observe a half-built system. Part of the Rubyist-perspectives build series (Aaron Patterson persona); field notes in docs/perspectives/field-notes/03-tenderlove.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
execute_plan now runs under Sync instead of a root Async block, so it joins an existing reactor (Falcon, nested tasks) instead of spawning a detached child and reading completion timestamps that were never set. Standalone callers are unchanged. apply_retry_backoff previously spawned a detached Async task to sleep and returned immediately, so retries never observed their configured backoff; it now sleeps in the current task, which the fiber scheduler keeps non-blocking for sibling tasks. Backoff specs now assert the orchestrator actually waits instead of stubbing Async::Task.current. Part of the Rubyist-perspectives build series (Samuel Williams persona); field notes in docs/perspectives/field-notes/05-ioquatix.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Remove the silent 'ollama' default access token that made the CLI's check_api_token! guard unreachable and turned misconfiguration into a request-time 401. Configuration#validate! now raises Agentic::Errors::ConfigurationError at LlmClient construction when neither a token nor an api_base_url is set. Base-URL-only setups (Ollama, etc.) remain supported via an explicit placeholder token. The library logger now defaults to :warn - the CLI raises verbosity for interactive use instead of the library narrating INFO lines into every host's stdout. Part of the Rubyist-perspectives build series (Jeremy Evans persona); field notes in docs/perspectives/field-notes/06-jeremyevans.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
CapabilityValidator compiles each CapabilitySpecification's declared inputs/outputs into memoized Dry::Schema definitions - putting the gem's existing (and previously unused) dry-schema dependency to work. Declared types are enforced, required keys required, undeclared keys still permitted. Violations raise Agentic::Errors::ValidationError carrying the capability name, the side of the contract that failed, and every violation at once, replacing the duplicated first-failure RuntimeError type checks in CapabilityProvider. Adds the previously missing CapabilityProvider spec coverage. Part of the Rubyist-perspectives build series (Piotr Solnica persona); field notes in docs/perspectives/field-notes/07-solnic.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
An append-only JSONL journal that wires into PlanOrchestrator's lifecycle hooks: one locked, flushed, fsynced line per task/plan event, with optional chaining through existing hooks so CLI observers keep working. ExecutionJournal.replay reconstructs completed work, outputs, and failures so a resumed process can skip tasks it already paid an LLM for; retry-then-succeed collapses to completed. Part of the Rubyist-perspectives build series (Mike Perham persona); field notes in docs/perspectives/field-notes/08-mperham.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Agent#execute_with_schema previously preferred the text_generation capability and silently discarded the schema argument, so tasks with output schemas lost their structure guarantees without a trace. It now prefers the LLM client (which enforces the schema) and raises SchemaNotSupportedError when only capability execution is available. FactoryMethods gains an inherited hook so subclasses receive their parent's configurable attributes and assembly instructions instead of silently starting empty. Agent.from_h no longer uses the ignored-block Agent.new constructor. String raises in Agent become typed errors (CapabilityNotFoundError, AgentNotConfiguredError, Errors::LlmError). All error classes are consolidated into lib/agentic/errors.rb so referencing the Errors namespace loads every class - sibling error constants split across files were only autoloadable after their file's namesake happened to load first. Part of the Rubyist-perspectives build series (Sandi Metz persona); field notes in docs/perspectives/field-notes/09-sandimetz.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Replace the hardcoded mock web_search implementation with Agentic::Capabilities::WebSearch: a zero-configuration DuckDuckGo Instant Answer backend (no API key, no new dependencies) behind a one-lambda seam for swapping in SerpAPI/Brave/Tavily/internal search. Non-JSON responses (blocked networks, proxy error pages) raise a descriptive Agentic::Error instead of a bare JSON::ParserError. Part of the Rubyist-perspectives build series (Andrew Kane persona); field notes in docs/perspectives/field-notes/10-ankane.md. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Logger#initialize(*args) folded keyword arguments into a positional hash that ::Logger reads as shift_age, so level: was ignored and the logger always ran at DEBUG. Forward with (...) so the :warn default (and any caller-supplied level) takes effect. Addendum to the Jeremy Evans persona build; field notes updated. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
…ound 2) Three poet agents compose linked verse under PlanOrchestrator dependencies; field notes record the output-piping and provider frictions hit while building with the gem. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Five tickets screened, categorized, and draft-replied in parallel via capability pipelines; field notes call out the agent-provider ceremony and task-payload workaround as the main consumer friction. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
One orchestrator task per lib/ file, each dissected with Prism; the gem audits its own method lengths. Field notes cover the regex-vs-parser lesson and why fiber concurrency doesn't speed up CPU-bound tasks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Maps a gem's constant tree via per-file survey tasks and Prism, auditing each file against the constant Zeitwerk expects - including the GemInflector version.rb special case the map itself initially got wrong. Field notes on verifying the verifier. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Measures orchestrator fan-out at concurrency 1/4/20 against ideal (within 10ms at every limit) and proves a plan shares a host reactor with sibling tasks instead of monopolizing it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Four deterministic DBA rules as capabilities, one review task per table; advisories with exact remediation. Field notes argue facts belong to rules and prose to models. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Extract/transform/load capabilities composed via registry.compose; malformed records are rejected at the first contract boundary with every violation named. Field notes on parse-optimistically, validate-at-the-boundary. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A forked child dies with exit! mid-batch; the parent replays the ExecutionJournal and finishes without re-paying for journaled work. Field notes on crash-testing durability and the idempotency-key gap it exposed. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Three deterministic critic agents (rules, squint test, naming) review a method in parallel; the sensei prescribes one smallest next step. Reviews the gem's own 90-line schedule_task. Field notes on multi-perspective review being buildable today from existing primitives. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Gem Scout rides the pluggable web_search backend with an offline index and a separate scoring capability. The perspectives README gains the round-2 table plus the consumer-side consensus: tasks need payloads, orchestrators should accept agents directly, dependents need output piping. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The consensus from ten personas building with the gem, implemented: - Task#payload carries arbitrary domain objects, opaque to the framework - add_task(task, deps, agent:) attaches an agent or bare callable directly; callables receive the Task and their return value becomes the output (CallableAgent adapter) - Dependency output piping: the orchestrator feeds completed dependency outputs into dependents (Task#dependency_outputs, Task#output_of); dependencies may be Task objects or ids - execute_plan's provider is now optional (fails fast when unresolvable) and accepts a block as a plan-wide agent factory - TaskDefinition#to_task bridges planner output to orchestrator input - registry.compose accepts inputs:/outputs: so composed capabilities get boundary validation like primitive ones - ExecutionJournal events carry task descriptions as cross-run idempotency keys; ReplayedState#completed? answers by id or name - README documents the concurrency contract (IO scales, CPU doesn't), direct-agent usage, and which layer to start with All six round-2 examples that carried the provider-adapter workaround are rewritten on the new API - each got shorter and lost its shared mutable state. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A rumor garbles its way through five villagers via dependency output piping alone - the feature round 2 asked for, exercised with zero scaffolding. Field notes compare the two rounds line for line. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Three parallel repo collectors fan into one writer task through dependency output piping - real git/TODO/spec data, no adapters. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
…xample schedule_dependent_tasks ran inside the completing task's semaphore slot, and spawning a dependent via semaphore.async blocks when the semaphore is full - so two slot-holders finishing together at a tight limit deadlocked waiting for each other's slots. Tasks now spawn through the barrier and acquire the semaphore inside the spawned fiber; the slot body is extracted into execute_task_in_slot. Regression spec covers the diamond-at-limit-2 case. Found by examples/plan_gantt.rb (tenderlove round 3), which renders a plan's execution as an ASCII timeline from lifecycle hooks - including queue-wait time, which is how the deadlock surfaced. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Per-file YARD coverage surveys fan into a single report task via dependency piping; 90.2% coverage measured, with the Thor-desc blind spot documented. Field notes on order-sensitive Prism traversal. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Lifecycle hooks feed an Async::Queue consumed by a renderer task in the same reactor - the promised streaming observability built from existing parts. Field notes document the hooks-run-inline contract. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Seed-deterministic bidirectional fuzz of every registered capability contract: conforming inputs must pass, dropped-required and type-corrupted inputs must fail. 34 trials, boundary holds, CI-ready exit code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Commands as composed capabilities with their own contracts (the round-3 compose inputs:/outputs: feature); dispatch is lookup + validation + rescue-to-rejection. Contract rejections and domain rejections stay distinguishable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Scripted-flaky task under exponential backoff with journaled retries; the timeline proves the backoff waits and the journal answers completed? by description across runs. Field notes flag the retryable-errors string matching and jitter default. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Lifecycle hooks record every orchestrator message and reply; the run renders as an ASCII sequence diagram, making the mediator pattern - and the newly framework-owned output hand-off - visible and teachable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Release notes drafted from real git history via a contract-checked classifier fanned across 40 commits into one writer. The perspectives README gains the round-3 table and findings: adapter tax eliminated, the Gantt-discovered deadlock fixed, and the next prioritized asks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The prioritized asks from the round-3 field notes, implemented:
- Named dependencies: add_task(task, needs: {shipped: commits}) pipes
outputs addressable as task.needs.shipped / task.needs[:shipped]
(NamedOutputs), composing with positional dependencies
- Task#previous_output shorthand for single-dependency chains
- task_slot_acquired lifecycle hook with waited: duration, separating
queue wait from run time; the Gantt example now renders '.' for
queued and '#' for running
- Retry policies consult the error's own retryable? verdict (captured
through TaskFailure.from_exception) before the retryable_errors type
list; Task#perform now preserves it too
- Contract value predicates: enum:, min:/max:, and non_empty: on
declared capability inputs/outputs, enforced via dry-schema
- Hooks documented as running inline on the task's fiber
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Three artists draw creature parts in parallel; the assembler reads them by name via needs: - round 3's named-dependency ask as a parlor game. Seeded, reproducible creatures. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Parallel environment checks with a named-dependency diagnosis and a CI-enforceable exit code - the onboarding wiki page, deleted. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Measures wall time and queue-wait (via the new task_slot_acquired hook) across concurrency limits and recommends where adding lanes stops paying - the long-pole flatline made visible. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Constant-reference graph between files via parallel Prism surveys and a fan-in atlas: load-bearing walls, heaviest leaners, and mutual dependencies. Field notes on namespace-relative constant resolution and the default-proc trap. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Two concurrent plans in one reactor bounded by a single credential-scoped Async::Semaphore; the high-water mark proves the ceiling holds across plan boundaries while calls interleave freely. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
…el example overall_status never consulted the :canceled state, so a canceled plan with no failures reported itself complete. Canceled tasks now yield :canceled. Found by examples/invariant_sentinel.rb (Jeremy Evans round 4), which checks domain invariants after every task via hooks and arrests the plan at the first broken law. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Order lifecycle where transition guards are enum predicates on capability contracts - no runtime transition table, illegal moves are type errors naming the legal alternatives, and output enums keep transitions honest about their destination. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Three failure modes under one retry policy: the rate limit's own retryable? verdict earns retries, the auth error's verdict overrules a deliberately-misconfigured type list, and opinion-less errors fall back to the list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Pre-execution design review of dependency graphs: god tasks, deep chains, orphans - with one prescribed first move. Its best finding is the missing read-only graph accessor three tools have now had to crowbar around. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
…ppet
Parses every ruby fence with Prism and resolves every Agentic
constant named against the loaded gem. First run caught the
capability-composition snippet's literal '{ data: { ... } }' - the
exact snippet round 1 flagged as docs-ahead-of-code - now fixed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Adds the round-4 table to the perspectives README: ten new experiments on the round-4 release, two more defects found by examples (canceled-status lie, four-round-old broken README snippet), and the next prioritized asks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
codenamev
left a comment
There was a problem hiding this comment.
Persona review panel: Aaron Patterson, Mike Perham, Sandi Metz. Verified locally: 540 examples, 0 failures at this cut.
Aaron Patterson (tenderlove) — The two fixes that matter here are correct in the way that counts: the suite-truncation repair (a CLI exit(1) killing rspec mid-run is the kind of bug that silently rots a whole project — 12 latent failures were hiding behind it), and the scheduler deadlock fix. Spawning through the barrier and acquiring the semaphore inside the fiber is the right shape — two slot-holders scheduling dependents at a tight limit can't wait on each other anymore, and the inline comment explains why, which future-me appreciates. Zeitwerk-as-single-loader with the boot benchmark receipt: good.
One nit to fix at the top of the stack (don't churn this slice): task durations are measured with Time.now deltas. Wall clocks step under NTP; everything downstream (journal baselines, percentiles in later slices) eats that noise. Use Process.clock_gettime(Process::CLOCK_MONOTONIC) for durations. Approving with that noted.
Mike Perham (mperham) — The journal is the piece I came to inspect. Locked, flushed, fsynced per event, one JSON line each: boring, correct, exactly what crash recovery needs. Descriptions as idempotency keys across runs is the design decision that makes resume actually work (ids are per-run; descriptions are stable). Errors testifying about their own retryability (retryable? on the error, consulted by policy) beats every string-matching retry table I've ever deleted. Canceled plans no longer lying :completed — good; the deeper cancel semantics get fixed properly in slice 4, which is the right place. Approve.
Sandi Metz — The seams are honest: add_task(task, deps, agent:) accepts a bare callable, results are objects (TaskResult/TaskFailure) instead of control flow, and execute_with_schema now does what its name promises. The factory subclassing fix pays down real inheritance debt. One note-only smell: ReplayedState#durations_by_description is a pure alias of durations — an extra name for the same message. Not worth churn now; don't add a third. Approve.
Panel verdict: approve (posted as comment; GitHub disallows self-approval). One action item carried to the top of the stack: monotonic-clock durations.
Generated by Claude Code
First slice of the persona-driven development series (rounds 1-4). Each cut point in this stack was a green-suite state.
Framework
exit(1)was killing rspec at 65/474) and the 12 latent failures it hidrequire_relativescheme; 19x faster require)PlanOrchestratorcomposes with running reactors; scheduler deadlock at tight concurrency fixed (barrier + acquire inside the fiber); canceled plans no longer report:completedExecutionJournal: fsynced JSONL crash recovery, descriptions as idempotency keys across runsTaskpayloads, direct callable agents,dependency_outputs, retry policy honoring backoff; errors testify about their own retryabilityweb_searchbackend replacing hardcoded fake resultsExamples & docs
Agentic.run, renga circle, ticket screener, latency lab, journal drills…) and field notes underdocs/perspectives/Stacked under #2 (rounds 5-7). Review here focuses on
lib/+spec/; examples are offline-runnable demos.🤖 Generated with Claude Code
https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF