• v1.1.0 d73c98f22d

    ktg released this 2026-08-14 05:04:30 +00:00 | 52 commits to main since this release

    No known key found for this signature in database

    Installing the attached wheel

    The wheel is not installable on its own, and the failure is a resolver error rather than a
    missing file: two dependencies are pinned to git tags, and [tool.uv.sources] does not travel with
    wheel metadata. Supply both requirements alongside it — this exact command was run against the
    attached file (measured: 65 packages, exit 0):

    uv pip install portfolio_optimiser-1.1.0-py3-none-any.whl \
      "llm-ingestion-okf @ git+https://git.fromaitochitta.com/open/llm-ingestion-okf.git@v0.3.2" \
      "llm-ingestion-guard @ git+https://git.fromaitochitta.com/open/llm-ingestion-pipeline-security.git@v0.3.4"
    

    The installed distribution finds its knowledge base without a checkout: shared_root() resolves
    into site-packages/portfolio_optimiser/_shared/, and the example bundles are there (verified
    against the attached wheel, not against a build made afterwards).

    Prefer a clone if you want to read the walkthrough against files in the tree — git clone plus
    uv sync needs none of the above.


    The release that makes the distribution stand on its own. 1.0.0 shipped a framework that could
    only run from a checkout; this one runs from an installed wheel and inside a Foundry-hosted
    container, and it is the first release whose artefacts are published alongside it.

    Added

    • shared/ now travels as packaged data. The wheel carries a byte-identical mirror of the tree
      under portfolio_optimiser/_shared/, and shared_root() resolves at call time in a fixed order:
      PORTFOLIO_SHARED_ROOT, then the working tree's shared/ when one exists, then the packaged
      copy. The working tree stays authoritative in a checkout — that is what keeps the pull-only
      subtree contract and the byte-exact goldens untouched. Measured before and after: the 1.0.0
      wheel carried 58 files and none under shared/; this one carries 122, of which 64 are the mirror.
    • A hosted entry point: main.py wraps run_project on a single asyncio loop and serves the
      Foundry hosting contract (GET /readiness, POST /invocations, SIGTERM → exit 0), with a
      Dockerfile and azure.yaml beside it. The invocation payload is whitelisted against
      run_project's own signature — an unknown field is refused by name with a 400 rather than
      silently dropped — and a rejected proposal is a successful run (200), because the negative outcome
      belongs to the payload and never to the transport.
    • Wheel-install instructions in the README. A wheel is not installable on its own: two dependencies
      are pinned to git tags, and [tool.uv.sources] does not travel with wheel metadata, so both must
      be supplied as requirements alongside the wheel. The published command is the one that was
      measured (65 packages, exit 0), not one composed afterwards.
    • Two gates on claims the published surface makes about itself: that env.template names the
      credentials backends.py actually constructs, and that the README's wheel-install command spells
      the version the build stamps on the file. Both read raw text and are line-anchored, because prose
      is the only place these claims live.

    Changed

    • The AZURE profile now reads its own environment rather than the operator's laptop. The
      endpoint resolves to the first non-empty of PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT and Foundry's
      injected FOUNDRY_PROJECT_ENDPOINT; precedence applies to values, so an exported-but-empty name
      falls through instead of masking a real one. The credential follows the same environment:
      AzureCliCredential on a developer host, ManagedIdentityCredential when
      FOUNDRY_HOSTING_ENVIRONMENT holds a non-empty value — never DefaultAzureCredential, whose
      probing would walk a credential chain that cannot succeed in a container and turn a config error
      into a slow one.
    • SECURITY.md states a deprecation notice period: at least one minor release and no fewer than
      30 days between announcement and removal, with security-critical removals named as the explicit
      exception. The supported-versions table is deliberately version-free, since a release number
      written there would drift at the next tag.
    • The README links the organisation's single canonical GOVERNANCE.md instead of vendoring a copy,
      and states the maintenance model (solo-maintained, no SLA, fork-and-own) on the first screen.
    • CLAUDE.md opens with an English note explaining what the file is for a visitor: the working
      agreement with the AI agent that builds this repository, doubling as its invariant ledger.

    Fixed

    • env.template claimed the AZURE profile resolved its credential through DefaultAzureCredential.
      It never has. An operator copying the template was told the wrong identity would be used.
    Downloads