Skip to content

Stack 3/5: Operations & relations — resize, journaled verdicts, relation-typed rules (rounds 8-10)#3

Merged
codenamev merged 36 commits into
mainfrom
claude/stack-3-operations-y0k02n
Jul 7, 2026
Merged

Stack 3/5: Operations & relations — resize, journaled verdicts, relation-typed rules (rounds 8-10)#3
codenamev merged 36 commits into
mainfrom
claude/stack-3-operations-y0k02n

Conversation

@codenamev

Copy link
Copy Markdown
Owner

Third slice (rounds 8-10), stacked on #2.

Framework

  • graph[:stats] gains roots:/leaves:; journal duration_samples + duration_percentile(desc, pct, last:)
  • RateLimit#resize(n): live ceiling changes (grow wakes waiters via Async::Semaphore#limit=, shrink drains); x-agentic-rules schema extension
  • Journal records retryable: at write time from the failure's own verdict; replay surfaces it
  • Relation-typed rules (Agentic::RelationRules): sum_lte / requires / mutually_exclusive declared as data — validator-enforced with derived messages, projected into real draft-07 keywords (dependencies, not-required pairs)
  • The retryable-nil convention: TaskFailure#hopeless? / #possibly_transient? (no opinion earns suspicion, not a death sentence)

Examples & docs

Review focus: lib/relation_rules.rb, journal changes, resize.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF


Generated by Claude Code

claude added 30 commits July 7, 2026 11:57
- graph[:stats] gains roots (no dependencies) and leaves (nothing
  depends on them) - the fortune teller's bread and butter
- ExecutionJournal replay accumulates duration_samples per description
  and ReplayedState#duration_percentile(desc, pct, last:) gives
  noise-resistant baselines over journal history
- to_json_schema emits structured rules as x-agentic-rules extension
  metadata (id, message, fields) on the inputs side; prose lambdas
  are honestly omitted

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The graph as a forest via stats[:roots]/[:leaves] - depth is altitude,
roots draw from the soil, leaves face the sun.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Basecamp's hill chart from lifecycle hooks: queued work climbs,
task_slot_acquired crests, done rolls down - risk visualization that
cannot be performed because positions are facts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Twenty journaled runs hunted with duration_percentile: a flaky task
with an innocent median caught by its 4.2x p90/p50 ratio. Averages
hide distribution shape; percentiles name it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Base/ours/theirs merge of plan wire formats: independent changes
combine, same-seam rewires conflict in topology vocabulary. Completes
the format trilogy (round-trip, diff, merge).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
AIMD congestion control converging on an undisclosed upstream
capacity from latency alone - the online complement to the knee
finder. Files limit.resize(n) as the round-9 ask.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Five integrity checks over the file five tools now trust blindly:
well-formed lines, monotonic time, causality, no double success,
non-negative durations. Four planted defects, seven findings.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Two contract versions semantically diffed with the variance asymmetry
named: inputs break when tightened, outputs break when narrowed.
Verdict computed as the version bump owed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Failures across journaled runs triaged by most-recent-attempt into
requeue (transient), parked (human must act), and recovered (not
dead) - with attempt counts from the journal's memory.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The plan's graph dictates the test plan: roots owe boundary
examples, joins owe one absence case per labeled tributary,
single-dep tasks owe a transform example, leaves owe artifact
assertions. Generates the RSpec skeleton from orchestrator.graph
using the new stats[:roots]/[:leaves].

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
One eval set scored four ways - exact, contains, tolerance, judge
rubric - through a single (expected, actual) -> score seam. Exact
match drowns the one real failure in wording noise; the right
scorer per field flags exactly the crash-ticket blind spot. Exits
1 by design when a real failure exists.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Adds the Round 8 table (ten experiments on the round-8 release)
and findings to the perspectives index, and regenerates the
examples catalog (70 examples). Next asks recorded:
RateLimit#resize and journaling retryable: at write time.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
- RateLimit#resize(n): change a live limiter's ceiling. Concurrency
  mode delegates to Async::Semaphore#limit= (waiters resume on grow,
  drain on shrink); windowed mode applies the new ceiling on the
  next admission check.
- ExecutionJournal records retryable: on task_failed at write time,
  from the failure's own retryable? verdict, and replay surfaces it
  in failures and events - triage survives taxonomy renames.

Modernizes the two examples that asked: adaptive_throttle now
steers one live RateLimit via resize, and dead_letter_office
triages from journaled verdicts instead of a read-time table.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Three journaled days read as a forecast: retryable failures are
weather (they pass), non-retryable ones are climate (a human must
dig a well). Built on the journal's new write-time retryable:
verdicts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A canary rollout as one resized RateLimit: dial up on health,
dial back on a burned p50 SLO, and hold after two burns - the
deployment strategy as a knob, not a platform.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
One limiter resized through ceilings 1-8, two clocks per job
(service vs total). The sweep locates the upstream's true
parallelism: past the knee throughput falls and the queue moves
invisibly to the server's side of the wire.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Seven invariants of the graph reflection API proved across four
plan shapes including a cycle. The prover's first catch was its
own author: depth has no meaning on cyclic graphs, so that
promise is scoped, not broken.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Two tenants behind one global ceiling: a FIFO door is fair to
requests, not tenants, so the 6-worker tenant quietly takes
triple. Per-tenant shares composed under the door restore
tenant-fairness, and resize lends an idle tenant's share to the
busy one live - topology fixed, only the numbers move.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Three assaults on RateLimit#resize: jagged ceiling epochs under
saturating load (concurrency recomputed independently), a
mid-flight shrink that must drain rather than evict or leak, and
a grow that must wake queued waiters immediately. Exit 0 is the
certificate.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Minimal and maximal fixtures derived from capability declarations,
proved against their own validator, with a mutant proving the
validator's teeth. Files the round-10 ask: relation-typed
structured rules so generators can satisfy cross-field constraints.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Closed/open/half-open breaker in two acts: three strikes for a
transient 503 outage, instant trip for a revoked key - the trip
decision fed by the journal's write-time retryable verdicts.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
One plan, five agent shapes through the single agent: seam -
lambda, stateful instance, Method object, curried proc, and a
nine-line decorator that stacks on any of them because it honors
the same one-message contract it consumes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Two candidates for one capability judged by one eval set on two
axes - accuracy and latency, same table. First-match clause order
vs summed evidence decides it; the scoreboard notes that a
perfect score means the eval set stopped discriminating.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Adds the Round 9 table (the operations round: ten experiments on
resize and write-time retryable verdicts) and findings to the
perspectives index, and regenerates the examples catalog (80
examples). Next asks recorded: relation-typed structured rules,
and a convention for retryable: nil in breakers.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
- Relation-typed structured rules via Agentic::RelationRules:
  sum_lte, requires, and mutually_exclusive declared as data. The
  validator enforces them (with derived messages), to_json_schema
  projects the expressible ones into real draft-07 keywords
  (dependencies, not-required pairs) and carries relation/limit in
  x-agentic-rules. Unknown relations raise loudly.
- The retryable-nil convention on TaskFailure: hopeless? (explicit
  false only) and possibly_transient? - no opinion earns suspicion,
  not a death sentence.

Modernizes the two examples that asked: contract_fixtures now
SATISFIES declared relations (scale, add, drop) and the validator
countersigns; circuit_breaker counts a strike for nil verdicts
instead of tripping instantly.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A form assistant that reads the contract aloud as questions:
requireds become requests, bounds become corrections, and
relation rules become their natural follow-ups - possible only
because the predicate is now data.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A complete endpoint derived from one capability declaration:
schema endpoint (with projected dependencies), structured 422s
that explain relation rules, and an output-guarded 201. The
business logic is four lines; the API layer just reads the
declaration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The validator benchmarked across contract sizes and rule counts,
priced as a fraction of the LLM call it protects: the biggest
contract costs 0.14ms against an 800ms round-trip, and the
rejection path is measured separately because failure costs more
than success.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Both renderings of the relation rules - Ruby validator and
draft-07 projection - evaluated over all sixteen presence
combinations and proven to agree, then the nil frontier surveyed:
typed fields guard it (agreement for different reasons), untyped
fields expose the true nil-vs-null divergence. Round-11 ask filed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Three measured drills on the cancellation paths: task-level
cancel is prompt (lane freed at 32ms, pending never bills), but
plan-level cancel under a joined reactor is bookkeeping wearing a
stop sign - status flips instantly while all six agents run and
bill. Filed as the round-11 ask with the drill as acceptance test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
claude added 6 commits July 7, 2026 13:50
Thirteen edge probes for the three relations against a
hand-written oracle (all pass, pinning contested semantics), then
one step off the paved road: a rule over an undeclared field fed
a string escapes as raw TypeError instead of ValidationError.
Exit 1 by design - the prober is the round-11 acceptance test.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Semver classification for the rules themselves: tightened limits
and widened demands break, removals are compatible, a changed
relation is a new law wearing an old name, and lambda rules keep
an honestly-labeled OPAQUE shrug - now a per-rule choice instead
of a ceiling on the tool.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
One fleet-wide retry wallet: transient failures spend from it,
hopeless ones cannot touch it (journaled verdicts + the nil
convention), and an empty wallet means failing fast - 45 doomed
calls cut to 17 during a full outage. Files the round-11 ask:
RateLimit#try_acquire for non-blocking admission.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
One policy written three ways - lambda, structured check,
relation - audited by four consumers (enforce, explain, generate,
project). All three enforce; the consumers multiply only when the
predicate is data. Choose representation by counting who must
understand it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
500 seeded-dirty rows through one contract: collect-don't-crash
via per-row rescue, a reject file with line, field, and rule for
every rejection, and the cross-field rows only relations catch -
all at 162us a row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Adds the Round 10 table (predicates become data: ten experiments
on relation rules and the nil convention) and findings to the
perspectives index, and regenerates the examples catalog (90
examples). Next asks recorded: prompt cancel_plan, type-safe
relation evaluation, RateLimit#try_acquire, and presence-semantics
alignment at the projection boundary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
@codenamev codenamev changed the base branch from claude/stack-2-graph-contracts-y0k02n to main July 7, 2026 23:29

@codenamev codenamev left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Persona review panel: Piotr Solnica, Mike Perham, Andrew Kane. Verified locally: 576 examples, 0 failures at this cut.


Piotr Solnica (solnic) — Relation-typed rules are the right call and the right shape: sum_lte/requires/mutually_exclusive as data means the predicate joins the declarations — enforceable, projectable, and (as the later semver tooling shows) diffable. Two details I checked and endorse: derived messages come from the declaration itself ("cpu + memory must total at most 100"), so violations are sentences without anyone writing them; and the draft-07 projection only emits dependencies/not-required for the relations that are actually expressible there, with sum_lte honestly confined to x-agentic-rules. Presence semantics (given-and-non-nil) documented at the module top. Lambda rules remain as the escape hatch, and opacity is now opt-in rather than the ceiling. Approve.

Mike Perham (mperham) — Journaling retryable: at write time from the failure's own verdict is the change I'd have demanded: retryability reconstructed at read time from class-name tables drifts the day someone renames an error; recorded when the error is fresh, it survives taxonomy churn, and the replay surfaces it for triage (the dead-letter and breaker examples in this slice show exactly why). The nil convention (hopeless? / possibly_transient?) splits the three-valued verdict at the joint policy code actually cares about — "no opinion" earning suspicion instead of a death sentence is correct. resize growing via Async::Semaphore#limit= so waiters wake immediately: good; the torture-test for it lands in slice 4 where it belongs. Approve.

Andrew Kane (ankane) — The practical surface here is strong: duration_samples + duration_percentile(desc, pct, last:) turns the journal into p50/p95 baselines for free, and stats[:roots]/[:leaves] got spent by four different tools within one round of shipping — the best evidence a reflection addition earned its place. One measured nit, not blocking: duration_percentile re-sorts samples on every call; fine at example scale, and callers doing tight loops can sort once themselves. Not worth an API change until a real workload complains. Approve.


Panel verdict: approve (as comment; self-approval disallowed). No new action items for the top of the stack.


Generated by Claude Code

@codenamev codenamev merged commit c01308e into main Jul 7, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants