Skip to content

Stack 2/5: Graph & contracts — reflection API, windowed limits, cross-field rules (rounds 5-7)#2

Merged
codenamev merged 36 commits into
mainfrom
claude/stack-2-graph-contracts-y0k02n
Jul 7, 2026
Merged

Stack 2/5: Graph & contracts — reflection API, windowed limits, cross-field rules (rounds 5-7)#2
codenamev merged 36 commits into
mainfrom
claude/stack-2-graph-contracts-y0k02n

Conversation

@codenamev

Copy link
Copy Markdown
Owner

Second slice (rounds 5-7), stacked on #1.

Framework

  • PlanOrchestrator#graph: frozen topology snapshot — order (Kahn's, cycles appended), labeled edges from needs:, stats (per-task depth, max_depth, max_fan_in)
  • RateLimit: windowed quota mode (per:), composition via #and (quota + connection pool at once)
  • Contract constraints beyond type/presence: enum:, min:/max:, non_empty:; cross-field rules: (all violations reported at once, structured rules with fields:/rule_violations); ValidationError#expectations
  • CapabilitySpecification#to_json_schema (draft-07 export)
  • Retry: backoff_jitter default with :full variant, injectable rng: for deterministic tests
  • Journal durations keyed by description (perf baselines)

Examples & docs

  • Rounds 5-7 persona builds: critical path, plan diagram, freight rules, 422 renderer, jitter shootout, plan round-trip with isomorphism proof, incident report, capability evals, and the referee pattern (exit-code-gated honesty tools)

Stacked on #1; stacked under the operations slice. Review focus: lib/plan_orchestrator.rb (graph), lib/rate_limit.rb, lib/capability_validator.rb.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF


Generated by Claude Code

claude added 30 commits July 6, 2026 21:21
The prioritized asks from the round-4 field notes, implemented:

- PlanOrchestrator#graph: frozen read-only snapshot of the plan's
  topology (tasks, dependencies, named needs) for tools that render,
  review, or analyze without crowbarring ivars
- ValidationError#expectations carries the declared contract for each
  violated key, so errors can name what would have been legal
- Cross-field contract rules: CapabilitySpecification rules: maps a
  description to a predicate over the whole input; broken rules are
  reported together under :base after per-key validation
- Agentic::RateLimit: credential-scoped concurrency ceiling with a
  high-water mark, shareable across plans; LlmClient accepts limiter:
- Retry backoff jitter defaults ON (floored at zero) so fleets don't
  retry in lockstep

The three examples that asked for these are modernized onto them:
graph_critic reads #graph, state_machine renders legal states from
expectations, shared_rate_limit uses Agentic::RateLimit. README
verifier confirms the new documentation snippets parse.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A quest as a plan: the map is drawn from orchestrator.graph before the
run, so the document and the program are one truth. Field notes ask
for a topological order in the graph snapshot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A running plan rendered as To Do / Doing / Done from two lifecycle
hooks; the WIP limit is the concurrency limit, enforced structurally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Graph topology + measured durations yields the wall-clock-bounding
chain, verified by experiment: an off-path task made instant changes
nothing; halving the on-path bottleneck moves the wall clock.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
orchestrator.graph emitted as Mermaid with named dependencies as
labeled edges - documentation generated from the artifact cannot
drift from it. Field notes propose graph[:edges] and graph[:order].

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Characterizes Agentic::RateLimit under three request waves: the
ceiling holds, the queue absorbs, and the per-wave wait table is the
capacity plan.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A tariff book as cross-field contract rules: all broken rules
reported at once, per-key validation shielding the rules from
nonsense. Policy and enforcement as one artifact.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A contract-agnostic error renderer built entirely from
ValidationError#expectations - allowed values and bounds travel
inside the exception, so one renderer serves every capability.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Twenty synchronized retries versus the new jitter-on default, as a
seeded, reproducible histogram: peak herd 20 -> 11. Field notes file
the full-jitter tier as the next notch.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
One workload as chain, star, and staged joins - wall time measured,
depth and fan-in read from the graph, trades stated. Star and staged
tie on speed, making the choice purely about design.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Generates examples/README.md from each example's own header and fails
on any example missing a run line - forty examples cataloged,
self-maintaining signage for the gallery.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Adds the round-5 table to the perspectives README: the ecosystem turn
- four tools built on the one-round-old graph accessor, every round-4
feature characterized under load, and the next asks (graph order and
labeled edges, structured rule identifiers, full jitter, windowed
rate limits).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The prioritized asks from the round-5 field notes, implemented:

- graph[:order]: topological sort via Kahn's algorithm (cycle members
  appended rather than dropped) - requested independently by three
  personas building graph tools
- graph[:edges]: positional and named dependencies pre-merged into
  frozen {from:, to:, label:} records, labels from needs: names
- Structured cross-field rules: rules may declare
  {message:, fields:, check:} keyed by identifier; prose-form rules
  keep working. ValidationError#rule_violations reports each broken
  rule with id, message, and the fields it reads, so UIs can highlight
  offending inputs
- backoff_jitter: :full draws delays uniformly from [0, delay] for
  harder herd-flattening than equal jitter
- Windowed rate limits: RateLimit.new(30, per: 60) admits at most
  ceiling acquisitions per rolling window (quota physics), alongside
  the existing concurrency mode (connection physics)

Modernized onto the new APIs: plan_diagram (edges + order),
dungeon_crawl (map in delve order), freight_rules (structured rules),
form_errors (policy violations highlight fields).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Any plan narrated as prose from graph[:order] and graph[:edges] -
needs: labels surface as purpose, and reading the plan aloud catches
sequence bugs before execution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
A gated pipeline run healthy and with a red canary: one
after_task_failure hook is the brake, canceled cars are reported as
CANCELED, and failure correctly outranks cancellation in the status.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Before/after plan measurement with a noise floor and critical-path
qualification: a PR that speeds up slack time while regressing the
path gets an exit-code veto.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Graph to JSON to fresh orchestrator and back, with an isomorphism
check: identity travels as description, structure as labeled edges,
behavior deliberately does not serialize.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The same twenty requests through a concurrency ceiling (done in 61ms)
and the new windowed quota (601ms): different physics, one class,
admission charts as proof.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Metamorphic audit of structured rules' field declarations: perturbing
undeclared fields must never flip a verdict. A seeded lying rule is
caught in 71 of 300 trials, with the UX harm explained.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Markdown reference docs emitted from the registry's contracts - types,
bounds, enums, and structured policies with their fields. One
declaration now validates, rejects, explains, documents, and gets
audited.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
None vs equal vs full jitter on one seeded scoreboard: peak retry
herd 40 -> 19 -> 13. Field notes give the operational guidance for
choosing a tier.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The god-join plan refactored in two small steps, each with a critic
verdict and a measured receipt - including the honest one: step 1
removed the smell and cost 30ms before step 2 paid it back.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Prices the declared graph against a model pricing table before
execution, gates on budget with a suggested fix, and reconciles
estimates against seeded actuals - spend as a gate and feedback loop.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Adds the round-6 table to the perspectives README: plans as artifacts
(narratable, serializable, priceable, diffable), declarations as
testable claims, and the next asks. Examples catalog regenerated at
50 entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The prioritized asks from the round-6 field notes, implemented:

- RateLimit#and composes limiters: a windowed quota and a concurrency
  ceiling enforced together (quota.and(pool)), nesting flattened
- graph[:stats]: per-task depth, max depth, and max fan-in computed
  once in the snapshot - three examples had hand-rolled this walk
- ExecutionJournal replay exposes per-task durations keyed by
  description, giving performance tooling a baseline source for free
- CapabilitySpecification#to_json_schema emits either contract side as
  draft-07 JSON Schema (types, enums, bounds, non-empty, descriptions)
- Retry policies accept rng: (any object with #rand) so jitter timing
  is injectable and reproducible in tests

refactor_receipts and graph_critic modernized onto graph[:stats].

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
graph[:stats] read as a palm - four checkable structural diagnoses in
a mystic's robe. Field notes argue charm is a rigorous API test and
ask for stats[:roots]/stats[:leaves].

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Three days of journaled plans replayed into a Friday check-in: what
shipped, what got stuck (with cross-run recovery detection via stable
descriptions), and where the time went via the new durations.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
This release judged against the journal the last release left behind
- description-keyed durations make the durability log double as the
performance baseline. Exit 1 on regression against recorded history.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Two plan wire-format versions diffed as topology - tasks added, edges
rewired, labels renamed - so plan review happens at design altitude
instead of JSON-line altitude.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
quota.and(pool) under load: both laws hold in their own dimensions
and the admission chart names the binding constraint. Ordering
contract (quota before socket) demonstrated and explained.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
claude added 6 commits July 7, 2026 11:23
Every strategy x jitter combination checked against its documented
envelope via the new injectable rng - containment AND coverage, a
thousand seeded draws each, CI-ready exit code.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The exported draft-07 schema raced against the live validator on 200
seeded payloads (balanced across accept/reject) - zero disagreements.
Establishes the house rule: every projection ships its referee.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
The 3am report generated from the journal: what ran, root cause with
retryability verdict, what never started (plan-vs-record complement),
and a resume plan with banked-work accounting.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
RuboCop for plans: four ten-line cops over graph[:stats] with
thresholds and reasons, including NamedFanIns - joins of two or more
must name their dependencies.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Golden test cases scored and gated against registered capabilities: a
contract-valid but substance-wrong parser caught at 33%. Contracts
check types; evals check truth.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF
Adds the round-7 table to the perspectives README: the referee round
- six exit-code honesty tools, the journal as four products, and the
next asks. Catalog regenerated at 60 entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FeZLdZ3M4q4cho4DZPfSkF

@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: Samuel Williams, Jeremy Evans, Xavier Noria. Verified locally: 562 examples, 0 failures at this cut.


Samuel Williams (ioquatix) — The limiter grows the right two shapes: a windowed mode (per:) for quota physics and #and composition for the real-world case of two laws at once (billed quota + connection pool). Composition acquiring outermost-first and the Composite flattening nested composites: correct, and the acquire-order comment ("own share first, then the door") matters — the reverse order is deadlock-shaped. One boundary to state plainly: at this cut the windowed stamp bookkeeping is check-then-act without a mutex — fine under a single reactor, coasting on the GVL under threads. I see slice 4 pays that debt properly; approving this slice with the caveat on the record rather than demanding churn here.

Jeremy Evans — Validation does the two things I insist on: it collects every violation instead of failing on the first (a bad payload should cost one round trip, not five), and ValidationError#expectations carries the declared contract for each violated key, so callers can render what would have been legal without side-channel knowledge. Cross-field rules: running only after per-key validation passes is the right sequencing — rules can assume typed values. enum/min/max/non_empty mapping onto dry-schema predicates rather than hand-rolled checks: good, use the library you already load. The injectable retry rng: earns its keyword — deterministic jitter tests instead of sleepy flaky ones. Approve.

Xavier Noria (fxn)#graph is a reflection API done with care: everything in the snapshot is duped and frozen (a reflection API that hands out live internals is a mutation API with plausible deniability), order is Kahn's with cycle members appended rather than silently dropped — the difference between a tool that degrades and one that lies — and edge labels derive from needs: so the two representations of naming can't drift apart at birth. The stats block (depth/max_depth/max_fan_in) computed once here saves every downstream tool a hand-rolled walk; later slices prove that bet pays. Approve.


Panel verdict: approve (as comment; self-approval disallowed). No new action items — the windowed-mutex caveat is already fixed in slice #4.


Generated by Claude Code

@codenamev codenamev merged commit d641871 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