infiquetra/fleet-core
Authored Fleet Core library: staffing (work shape, role, and lens to model and effort), the tier palette and resolver, shared retry and backoff, the run-start intent envelope, the TypeSafe judgment client, and the delegation audit. Consumers receive the modules they declare as build-time bundles.
Changelog
All notable changes to Fleet Core are documented in this file.
The format is based on Keep a Changelog. From 0.32.0 this package is authored here. The version is this package's version. The import below kept the upstream version number. Older entries describe the derived slice and are left as the record of those releases.
The catalog requires python>=3.12.
[Unreleased]
Added
- The sweep's language list gains
cdk, and the workflow id isgithub-workflow(infiquetra-agent-plugins #224), matching saga's formula lists. - The Langfuse client reads two more lists over
GETonly:traces(/api/public/traces) andscores-list(/api/public/v2/scores), for saga's review-outcome job (infiquetra-agent-plugins #167). The method set staysGETandPOSTonly, on fixed paths.
Changed
-
Presentation metadata (author, repository, license, and keywords) now lives in the portable
plugin.json, and the generated Codex manifest follows it. -
The Muse model in
staffing.jsonis nowmuse-wonder-full-1.0for every model it maps (gpt-5.6-sol,gpt-5.6-terra,gpt-5.5), replacingmuse-spark-1.3-contributor.
[0.33.2] - 2026-10-07
Changed
- Haiku efforts move up one rung (operator decision, 2026-10-07):
purely-mechanicalandoffload-test-gatedhaiku/medium,mechanicalhaiku/xhigh,read-only-surveyhaiku/max;implementation-test-gatedstays haiku/xhigh.maxjoins the Claude effort palette for haiku only, with haiku's raise ceiling at xhigh so no raise lands on haiku/max. The expensive-effort confirmation gate is the top effort of a model that is not cheap (xhigh), so no haiku tier asks for confirmation. A recorded Jev raise above the target model's raise ceiling is now refused, the same boundone_step_raisekeeps. The effort rider gains amaxline.
[0.33.1] - 2026-10-07
Changed
- Re-tier the staffing defaults for Haiku 5.5 and the 2026-10-07 Sonnet 5.5 cache-read cut:
implementationsonnet/high, newimplementation-test-gatedhaiku/xhigh,mechanicalhaiku/medium,read-only-surveyhaiku/xhigh,offloadsonnet/high. Haiku's effort ceiling is xhigh, and a per-modelraise_ceiling(sonnet: high) sends a raise from sonnet/high to opus/high. The bundled copies in mission-control and saga are regenerated.
Added
-
Issue 166:
langfuse_client, a standard-library client for saga's own Langfuse project. It reads onlySAGA_LANGFUSE_PUBLIC_KEY,SAGA_LANGFUSE_SECRET_KEYandSAGA_LANGFUSE_HOST, puts the key pair only in the basic-auth header, removes Langfuse key shapes and then runs TypeSafe's redaction on every payload, refuses a private or unrecorded repository over plain HTTP (naming X3), sends a public one over plain HTTP only to a loopback or private, non-link-local address, follows no redirect, and reaches a fixed list ofGETandPOSTendpoints only.references/langfuse.mdholds the rule. Saga's bundle includes it. The package version stays 0.33.0. -
Issue 156:
jev sweepclassifies pieces into a where-to-look list of at most 30 items and stops at $1. A failed classifier returns no items, and the review continues. Saga's bundle includesjev_sweep. The package version stays 0.33.0. -
Issue 158: a
consequenceJev verb, one choice over saga's eleven review consequences in the closed list's order (floor 0.60), which saga's targeted-reviewer check asks about each reproduced finding; and atargeted-reviewerstaffing role at thejudgmentwork shape with theadversarial-reviewcapability.typesafe.mdnames the verb and its caller. The bundled copies in mission-control and saga are regenerated. -
jev_log.record_invalidationappends aninvalidationrecord naming one verdict by hash (#111). The verdict log is append-only, so a verdict whose label turned out to be bogus is marked, never rewritten; the bundled copies in mission-control and saga are regenerated. -
The evaluation harness honors invalidations:
jev_eval.load_recordsdrops invalidated verdicts and now returns(records, skipped, invalidated), andEvalReportcarries the count (invalidated, into_dict()andrender()).evaluate()takes matchinginvalidated=input.typesafe.md§2 documents the new record kind.
[0.33.0] - 2026-10-04
Adds the tier judgment and the implementation work shape to staffing, and removes the ordinal cost-weight module.
Added
- The tier judgment (issue #96). The
tierverb gains adirectionquestion (below, same or above the task'sdefault_tier) and anauto_floorof 0.80 beside its 0.60 confidence floor;Verbhas a newauto_floorfield.staffing.classify_judgmentsorts an answer into a band (auto-raise,confirm-raise,raise-at-ceiling,advisory-lower,agrees,log-only,not-consulted); onlyauto-raiseapplies, and nothing ever lowers a tier.staffing.one_step_raise(one step, effort first, never to fable or pastxhigh),one_step_lower(display only),tier_direction(the verdict label),jev_raise_from,record_tier_verdicts,judgment_unitandtiering_enabledare new. INFIQUETRA_TYPESAFE_TIERING=offswitches the tier judgment off; the consult returns before the client is loaded and makes no request.jev_log.record_verdicttakesstate_hash=andquestions_hash=in place ofstateandquestions, so a verdict can be logged once its label is known; it refuses a call with neither.typesafe.md§7 documents the tier judgment, and house rule 10 states its raise-only exception.fleet_commons.effort_riderunderstands a fourth spawn kind,claude-agent-type: a subagent dispatched as an agent type whose definition carries the resolved model and effort (saga's Claude Code mod, issue #106). It is a real-knob pass-through, soinject_effortreturns the prompt unchanged andreconcile_effortcompares the observed request effort throughmanifest_effort. Theagentrider is unchanged and stays the fallback.staffing.jsongains theimplementationwork shape atopus/medium, for implementing a settled plan unit including its tests, and theworkerrole now points at it (issue #93). The merging and release workers stay onmechanicalatsonnet/medium.- A
work_shapesrow may carryclaude_only: true.staffing.resolve_shapethen refuses any non-Claude vendor, naming it, rather than translating the tier into that vendor's execution class.implementationis the one such row. No schema version change:work_shapesis outside the portable subset shared with the Codex plugin repository. - A
work_shapesrow may carryunattended_step_down: false, which keepsintent_envelope.recommend_tierfrom stepping an unattended run one rung cheaper.implementationcarries it. staffing.resolve_shapeandstaffing.resolve_roletakeanswer=(the operator's explicit tier) andjev_raise=(a raise recorded in the run record).staffing.TIER_PRECEDENCEwrites the order once: operator answer, repository overlay, recorded raise, registry default. A recorded raise that is not exactly one model rung or one effort rung above the default, or that namesfable, is refused.staffing.unit_work_shape_default()returns theworkerrole's work shape, the default for an undeclared build unit, andstaffing.unattended_step_down()reads the new row flag.test_tier_resolver.py::test_skill_registry_syncand its seeded-divergence twin, the guard the/plantier table's marker has named since the table was generated but that did not exist.
Changed
staffing.consult_tier_suggestionsasks thedirectionquestion, one per unit in one request, with the issue (issue=) and each unit's task beside its default tier as state. It returnsjudgments(wassuggestions), logs nothing itself, and takesgetenv=,cache=andauto_floor=;log_verdicts=andlog_dir=are gone. Decision ids use the new prefixstaffing/tier-direction.SUGGEST_DECISION_PREFIX,SUGGESTED_EFFORT_ALIASESand the operator-override record for a differing suggestion are removed.TIER_POLICYnames every work shape's default exactly asstaffing.jsondeclares it (it said mechanical work runs on Haiku), and thetierverb's model and effort choices are the palette: fable, opus, sonnet, haiku and low, medium, high, xhigh. A test holds the policy tostaffing.jsonin both directions.staffing.py resolve --suggestprints ajudgment:line with the direction, confidence, both floors and the band it would take in a run;applies:stays the default.references/staffing.mddescribes the registered-type route and keeps the rider as the fallback, records that Claude Code 2.1.289 honorseffort:in a plugin agent file (read from the build's loader), and corrects the agent-file paragraph: agent files live under the Claude adapter, and the lint it named is not in this repository.intent_envelope.recommend_tiertakes its base fromstaffing.resolve_shape(so the repository overlay applies) and acceptsroot=.render_tier_table.pyrenders animplementationrow.tier_resolver.resolve'senvelope_ceilingandoperator_overridearguments are documented as deprecated; an operator's tier goes throughstaffing.resolve_shape(answer=...).
Removed
- The ordinal cost-weight module, its JSON table and its test. The ordinal cost table rated
opus/mediumat 2.67 timessonnet/medium, about double the measured gap, and nothing outside its own test read it.
Security
- The tier judgment's recorded reason carries only the direction question's own choices (issue
#133).
staffing._probabilities_textused to copy every probability key from the TypeSafe answer into the reason, and that reason reachesjev_raise, which/workhands to a shell command. It now rendersbelow,sameandabove(the newstaffing.DIRECTION_CHOICES), in that order, and drops any other key. The bundled copies in saga and mission-control are regenerated.
[0.32.0] - 2026-09-22
0.32.0 — imported in full from infiquetra-claude-plugins@acc99fe7 (upstream 0.32.0); authored here from this commit; no provenance manifest from now on.
Added
- The full
scripts/fleet_commons/module set at that commit, plusscripts/jev.pyandreferences/. Package tests live underplugins/fleet-core/tests/and import those modules directly. - A module that needs a sibling loads
<this directory>/<name>.pyinstead offleet_commons_shim. The same file works in this package and in a generated_bundled/copy.scripts/fleet_commons_shim.pyis not imported.
Changed
plugin.jsonversion is0.32.0.PROVENANCE.jsonis gone. Bundle stamps for an authored package record that version andsource-commit: authored. The source digest still proves the bundled bytes match the module.tier_palette.pyreadsstaffing.jsonat import. The 0.25.2 slice readmodels.json. The model and effort ladders are the same four names.retry_backoff.parse_retry_afterclamps a negative delta-seconds hint to0.0, the same answer an already-past HTTP-date already produced.typesafe_client._sdk_callrefuses an unprepared body before it importstypesafe-sdk, and it uses an injected client factory without requiring that package. This catalog does not install the SDK. When the SDK is installed and no factory is injected, the call still goes through it.- Mission-control's bundle declaration gained a
staffing.jsondata entry so the already-declaredtier_palettemodule can import. The module list is unchanged.models.jsonstayed declared and stayed in this package for a time; see the Residual entry below andDEFERRED.md.
Residual
scripts/fleet_commons/models.jsonwas absent fromacc99fe7and was kept becauseplugins/mission-control/fleet-bundle.jsonstill declared it. Cleared 2026-09-22: noplugins/*/fleet-bundle.jsondeclares it and no shipped Python reads it; the file is deleted. SeeDEFERRED.md.
Dropped tests
Upstream tests whose premise is the upstream repository layout were not
ported. The catalog's own tests/test_intent_envelope.py,
tests/test_retry_backoff.py, and tests/test_tier_palette.py stay.
Whole files:
tests/test_agent_tier_lint.py— globs every upstreamplugins/*/agents/*.md.tests/test_agent_tiering.py— pins agent frontmatter in plugins this catalog does not carry.tests/test_delegation_fleet_monitor.py— readsscripts/check_delegation_proof.pyandmarketplace/bridge_plugins.json.tests/test_fleet_commons_resolution.py— the discovery shim and byte-identical vendored copies across upstream plugins.tests/test_intent_envelope.py— saga's re-export, a repo-wide drift guard, and saga's intent-envelope reference.tests/test_mission_control_suggest.py— mission-control triage scripts this package does not carry.tests/test_parse_issue_flags.py— saga'sparse_issue.py.tests/test_saga_spec_consumer_row.py— saga's plan-save contract.tests/test_typesafe_sdk_pin.py— the upstream repository'spyproject.tomlpin oftypesafe-sdk.tests/test_work_build_unit_tier.py— saga's work skill andlifecycle_state.py.
Cases removed from files that were otherwise ported:
test_tier_resolver.py:test_skill_md_has_generated_tier_table_markers,test_skill_registry_sync,test_skill_registry_sync_catches_seeded_divergence,test_effort_emitted_into_plan_tier_table(saga's plan skill and team-execution).test_tier_vocab_single_source.py:test_plan_table_render_synced(saga's plan skill).test_staffing_suggest.py:test_admission_embeds_one_suggestion_per_role,test_admission_without_suggest_is_unchanged,test_admission_suggest_degrades_without_consult,test_admission_suggest_falls_open_on_client_error,test_admit_threads_suggest_to_one_verdict_per_role(saga'sadmission.py).test_merge_guard.py:TestOrchestrateAgreesWithTheSharedGuard(orchestrate is not in this catalog).test_jev_eval.py:test_the_seeded_benchmark_file_exists_and_is_well_formed,test_the_benchmark_reproduces_ten_of_ten,test_the_benchmark_run_touches_no_transport(upstreamdocs/analysisresearch inputs).test_jev_cli.py:test_the_seeded_benchmark_reproduces_ten_of_ten,test_eval_json_mode_reports_bands,test_eval_makes_no_transport_call(the same research inputs).test_effort_rider.py:test_loadable_via_fleet_commons_shim(the shim is not shipped;test_loadable_from_its_own_directorycovers the module).test_typesafe_client.py:test_sdk_transport_returns_the_same_shape_as_urllib,test_sdk_transport_receives_the_key_explicitly,test_sdk_exception_text_is_composed_here_not_by_the_vendor(they require thetypesafe-sdkpackage), andtest_a_real_lock_file_hunk_is_not_shredded(it reads the upstream repository'suv.lock).
Unreleased
The entries under Changed record catalog-level contract changes that moved no
ported bytes; they carry no release tag. The entries under Added record the
slice expansion of 2026-08-24, which added ported files at the existing pin
without moving any byte already here. Neither group advances the package
version: this package's version tracks the upstream Fleet Core version its
bytes derive from (0.25.2 at commit 3b5faa6c), and upstream's 0.25.3 release
of 2026-08-24 changed retry_backoff.py, which this pin deliberately does not
take — a repin would churn UniFi's bundles and invalidate its committed
matrix. Naming this package "0.25.3" while it still carries 0.25.2's
retry_backoff bytes would collide with the real upstream release, and
inventing any other number would imply the second writable source this
changelog's convention exists to prevent.
Changed
-
The portable UniFi package no longer pins the same upstream revision as this package, and no Fleet Core byte moved. UniFi
2.0.1, at upstream commit0d81dd9a, repaired the caller half of theRetry-Afterdefect this package's0.25.1release fixed in the primitive: both UniFi clients converted the raw header withint()before raising, so the repaired primitive never received a header it could read.plugins/unifi/PROVENANCE.jsontherefore pins0d81dd9a, while this package still pinsed72f439. The upstreamplugins/fleet-coresubtree is byte-identical between those two revisions, so the two pins name one consistent upstream state, not two competing answers. The[0.25.1]entry below says the two packages pin the same revision; that sentence describes what was true at that release and is left standing rather than rewritten. -
The catalog's minimum supported Python is
python>=3.12. It is a minimum and not a pin: every later interpreter stays in contract. The floor is now the one the authoritative source declares and tests.infiquetra-claude-pluginssetsrequires-python = ">=3.12"in its project file and pins3.12in every continuous-integration job, at the same commited72f439this package is derived from. A derived catalog must not promise more compatibility than the source it is derived from, so the lower floor this catalog used to document was a promise nothing upstream was keeping. The decision and its reasoning are recorded in the repository's engineering journal.
Added
- The mission-control closure joins the slice: three files at the same pin.
scripts/fleet_commons/intent_envelope.py,scripts/fleet_commons/tier_palette.py, and thescripts/fleet_commons/models.jsonregistry are ported at fleet-core pin3b5faa6c. Mission-control's shipped surface reaches exactly this closure: its issue-capture path loads the envelope module's parse/render surface, andIntentEnvelope.validate()reaches the tier palette whenever a parsed envelope carriesspend_envelope.tier_ceiling; the palette reads its sibling registry at import time, so the data file rides the slice. The resolver leg behindrecommend_tierhas zero callers in either consumer and stays deferred. tier_palette.pyandmodels.jsonare pure byte copies; the repository validator recomputes their digests againstPROVENANCE.jsonon every run.intent_envelope.pyports under this package's existingdeterministic-transformcustody class with the new named ruleresolve-fleet-commons-siblingversion 1: the module's Claude-Code-specific discovery-shim import block and its two shim load call sites become same-directory sibling resolution — placement-independent, so the identical file works in this package and in any generated_bundled/copy a consuming plugin carries. A deferred name (tier_resolver) fails at call time naming the missing sibling path, never at import. Every other line is a byte copy.- The deferred inventory is regenerated, so exactly the three rows move
from deferred to ported and every other deferral stays explicit; the
provenance manifest classifies all three files and names them, with the two
new target-owned tests, in the release surface. The decision is KTD8 in
docs/plans/2026-08-24-mission-control-port-run-plan.md.
[0.25.2] - 2026-08-22
Re-synchronized from Fleet Core 0.25.2 in infiquetra-claude-plugins at commit
3b5faa6c. Custody did not move. The repair was authored, reviewed, and
released upstream and taken here by re-synchronization, which is the second
exercise of this slice's rule.
Fixed
- A non-finite
Retry-Afterno longer costs the caller its typed rate-limit surface.float()acceptsinf,-inf,nan, and any overlarge literal such as1e400, soparse_retry_afterreduced a header carrying one of those to a non-finite "delay" and returned it as though the server had given a usable hint. The sleep path hid it:infclamped tomax_delayandnanfailed its> 0test, so every retry behaved correctly. The damage landed only once retries were exhausted, where a caller reduces the hint to whole seconds to say how long to wait —math.ceil(inf)raisesOverflowErrorandmath.ceil(nan)raisesValueError. Both UniFi clients catch that in a broad handler, so the operator was toldUnexpected error: cannot convert float infinity to integerinstead of a wait time, and the typed 429 surface that 0.25.1 exists to preserve was destroyed at exactly the moment it was needed.1e400is the shape that matters in practice: an ordinary overlarge integer in a header, nothing exotic. - A non-finite value is now the "no usable hint" case the function already
documented, so it yields
Noneand the caller falls back to computed jittered backoff. The rule covers the numeric path as well as the string one, because a caller that parses its own header hands the number straight in.
0.25.1 - 2026-08-22
Re-synchronized from Fleet Core 0.25.1 in infiquetra-claude-plugins at commit
ed72f439. Custody did not move. The repair was authored, reviewed, and
released upstream, and this package took it by re-synchronization rather than by
an edit to the ported bytes, which is the rule this slice was created under and
the first time that rule has been exercised.
Fixed
- A
Retry-AfterHTTP-date now backs the request off instead of killing the call. RFC 7231 section 7.1.3 allows the header in two forms, a count of seconds and an absolute date, and real controllers send the date form.scripts/fleet_commons/retry_backoff.pyunderstood only the number, so a caller that converted the header withint()raisedValueErrorinside the retried call. AValueErrorcarries no status code, so the primitive judged it non-retryable and re-raised it on the first attempt: one request, no backoff, and a generic error in place of a rate-limit error. The new publicparse_retry_after(value, *, now=time.time)reduces either form to a non-negative delay in seconds, and returnsNonefor an absent, empty, or unparseable value, which the caller reads as "no usable hint" and answers with computed jittered backoff. A date already in the past parses to0.0, never a negative delay. Clamping and jitter are untouched, so an absurd date and an absurd number are bounded identically.retry_with_backoffgains a keyword-onlynowseam so a date resolves deterministically under test, and theretry_aftercallable's type widens tofloat | str | None, which is additive.
Changed
- The pinned source revision.
PROVENANCE.jsonandDEFERRED.mdnow name commited72f439and Fleet Core0.25.1. The portable UniFi package pins the same revision, so one commit names the corrected state of the whole port. - The ported test suite grew from ten test functions to eighteen, and its
guard-pytest-importtransform moved to version 2. Upstream's new coverage includes two tests carrying@pytest.mark.parametrize, and a decorator is evaluated when the module is imported. Version 1 boundpytesttoNonewhen the dependency was absent, which would have made the dependency-free baseline job raiseAttributeErroron a module it never runs. Version 2 raisesunittest.SkipTestinstead, whichunittestrecords as one skipped test, so the baseline job stays green and says out loud why it collected nothing here. - The bundled copies shipped to consuming plugins carry the new stamp:
source version
0.25.1, source commited72f439, and the new source digest.
Known issues
-
Resolved on 2026-08-22, after this release. The catalog's floor moved to
python>=3.12, which is above what this release needs, so this release is no longer out of contract with the catalog that carries it. The floor moved for a reason larger than this one import: it now matches the floor the authoritative source declares and tests. See the Unreleased section above. The entry is preserved as written:This release needs Python 3.11 or newer, which is above the Python 3.10 floor this catalog documents. The corrected module imports
UTCfromdatetime, an alias that exists only in Python 3.11 and newer, so importing it under Python 3.10 raisesImportError. The byte-copy rule forbids repairing that here: a downstream edit would make this path diverge from its source and would giveretry_backoffa second writable source. Either the repair is authored upstream or the declared floor moves to 3.11. The decision is open and recorded in the repository's engineering journal.
0.25.0 - 2026-08-22
Initial portable slice, derived from Fleet Core 0.25.0 in
infiquetra-claude-plugins at commit 13b0234.
Added
- The shared 429 retry and backoff primitive, as an upstream byte copy.
scripts/fleet_commons/retry_backoff.pycarriesretry_with_backoff,CircuitBreaker,bridge_call, andCircuitOpenError. It is standard library only and pure over injectedsleep,rng, andclockseams, so its tests are deterministic and no real time passes. The file is byte-identical to its source; the repository validator recomputes its digest againstPROVENANCE.jsonon every run, so a hand edit here fails validation rather than surviving as silent divergence. - The upstream test suite, ported with its ten tests unchanged.
tests/test_retry_backoff.pyat the repository root. Every line fromclass RateError(Exception):onward is a byte copy. The single deviation is a guardedpytestimport, recorded inPROVENANCE.jsonas deterministic transformguard-pytest-importversion 1, which lets the repository's dependency-free baseline job import the module without pytest installed while the ported plugin job still runs all ten tests. - A generated inventory of everything this slice does not carry.
DEFERRED.mdnames each upstream item absent from this package: fifteen Python modules, three data files, and the Claude-specific shim module. It is derived from the pinned source tree byscripts/generate_deferred_inventory.pyas a set difference rather than typed, so a module added upstream fails the check until the file is regenerated. - A provenance manifest pinning the derivation.
PROVENANCE.jsonrecords the source repository, the source commit, the Fleet Core version, and a per-file classification and digest.
Notes
- This package is one vertical slice and claims no Fleet Core parity. Consuming plugins receive the module as a generated, stamped, read-only bundle produced at build time, so no user installs Fleet Core separately.
- The portable catalog documented a 3.10 floor at this release. That floor was
superseded on 2026-08-22; the catalog's contract is now
python>=3.12, as the Unreleased section above records. The ported module itself carriesfrom __future__ import annotationsand needs nothing beyond the standard library.