ossattr

package
v1.799.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 12, 2026 License: Apache-2.0, MIT Imports: 5 Imported by: 0

Documentation

Overview

Package ossattr is the pure, deterministic attribution core of the SBOM-driven OSS-developer payout system. It answers exactly one question:

Given an org's Hanzo cloud spend and the set of OSS packages present in
the SBOM(s) of what that org runs, how much of that spend is owed to each
OSS package — under a capped, weighted, pro-rata policy?

It is a LEAF package: it imports only the standard library, so the attribution math is independent of commerce server internals, the datastore, ZAP, or HTTP. That makes the model the one place the fairness rules live, and makes it exhaustively testable as a pure function.

Design (one way, decomplected):

  • The POOL is a fraction of spend, hard-capped at 25%. Hanzo keeps the rest. The cap is the headline promise ("up to 25% of all Hanzo cloud costs go to upstream OSS") and is enforced here, in code, not by convention. Pool = spend * min(PoolFraction, MaxPoolFraction).

  • Each package gets a WEIGHT from the policy. There is exactly one mechanism — pro-rata by weight — and the policy supplies the weights. Direct vs transitive is not a special case baked into the mechanism; it is two numbers in the policy (DirectWeight, TransitiveWeight). A per-package criticality multiplier is also just data. This keeps the mechanism (split a pool pro-rata) orthogonal to the fairness knobs.

  • A package's share = Pool * (weight_i / Σ weight_j).

  • The split is in integer cents and conserves the pool exactly: the sum of allocated cents equals the pool to the last cent (largest-remainder apportionment), so no money is created or lost to rounding.

The function is total and deterministic: identical inputs always produce identical outputs, including a stable ordering, so the same accrual is reproducible and auditable.

Index

Constants

View Source
const MaxPoolFraction = 0.25

MaxPoolFraction is the absolute ceiling on the OSS pool: at most 25% of an org's Hanzo cloud spend is ever attributed to OSS dependencies. Any policy requesting more is clamped to this value. This constant IS the "up to 25%" promise; it lives in code so it cannot silently drift.

Variables

This section is empty.

Functions

func AccrualID

func AccrualID(orgID, txnID, purl string) string

AccrualID derives a stable, deterministic idempotency key for an accrual line so the same (org, spend transaction, package) is never double-accrued. It hashes the tuple; callers store it as the accrual's idempotency key.

Types

type Allocation

type Allocation struct {
	PURL       string
	Name       string
	Ecosystem  string
	Version    string
	Scope      Scope
	Weight     float64 // final weight used (base*criticality)
	ShareRatio float64 // weight / totalWeight, in [0,1]
	Cents      int64   // attributed amount, integer cents (apportioned)
}

Allocation is the attribution result for one package: how many cents of the pool it earns, plus the inputs that produced it (for a fully auditable ledger line — anyone can recompute share = weight/totalWeight * pool).

type Package

type Package struct {
	PURL        string  // canonical Package URL — the identity
	Name        string  // human name, e.g. "github.com/gin-gonic/gin"
	Ecosystem   string  // "golang" | "npm" | "pypi" | "apk" | "deb" | ...
	Version     string  // resolved version, e.g. "v1.12.0"
	Scope       Scope   // direct | transitive
	Criticality float64 // policy multiplier; 0 or negative means "use 1.0"
}

Package is one OSS dependency observed in an SBOM. It is identified by its Package URL (PURL, https://github.com/package-url/purl-spec), the ecosystem- neutral coordinate emitted by CycloneDX/SPDX (e.g. "pkg:golang/github.com/gin-gonic/gin@v1.12.0", "pkg:npm/react@18.3.1", "pkg:pypi/fastapi@0.110.0"). The PURL is the join key across SBOMs, the accrual ledger, and the maintainer resolver.

type Policy

type Policy struct {
	// PoolFraction is the share of spend allocated to the OSS pool, e.g. 0.25
	// for the full 25%. Clamped to MaxPoolFraction. A lower value lets Hanzo
	// ramp the program up (e.g. 0.10) without ever exceeding the promise.
	PoolFraction float64

	// DirectWeight and TransitiveWeight are the base per-package weights by
	// scope. Defaults: direct = 1.0, transitive = 0.25. A package's final
	// weight is base(scope) * criticality.
	DirectWeight     float64
	TransitiveWeight float64
}

Policy parameterizes attribution. All knobs are data; the mechanism is fixed. The zero Policy is NOT valid — callers should start from DefaultPolicy and override. PoolFraction is clamped to [0, MaxPoolFraction].

func DefaultPolicy

func DefaultPolicy() Policy

DefaultPolicy is the canonical starting policy: the full 25% pool, direct deps weighted 4x a transitive dep, criticality off (1.0) by default.

type Result

type Result struct {
	SpendCents   int64        // the input spend
	PoolFraction float64      // the effective (clamped) pool fraction applied
	PoolCents    int64        // spend * poolFraction, floored — the amount split
	TotalWeight  float64      // Σ weights over all attributable packages
	Allocations  []Allocation // per-package, sorted by PURL (stable)
	// UnallocatedCents is pool cents that could not be attributed (no packages
	// or zero total weight). It is held, not lost — the caller routes it to a
	// held pool. Always 0 when there is at least one positively-weighted pkg.
	UnallocatedCents int64
}

Result is the full attribution of one spend amount across a package set.

func Attribute

func Attribute(spendCents int64, pkgs []Package, policy Policy) Result

Attribute is the heart of the system: a pure, total, deterministic function from (spend, packages, policy) to per-package cent allocations.

Contract:

  • Pool = floor(spendCents * clamp(policy.PoolFraction, 0, 25%)).
  • Each package weight = base(scope) * criticality.
  • share_i = pool * weight_i / Σ weight_j, apportioned to integer cents by largest remainder so Σ allocated cents == pool exactly.
  • Packages are de-duplicated by PURL (the highest-weight instance wins; ties keep the first seen) so the same dep across multiple SBOMs is paid once. Duplicate handling is deterministic.
  • With no packages, or all weights zero, the whole pool is Unallocated (held), nothing is invented.

Allocations are returned sorted by PURL for stable, reproducible output.

type Scope

type Scope string

Scope classifies how a package entered the dependency graph. A direct dependency is declared by a deployed Hanzo service; a transitive dependency is pulled in by another dependency. The two carry different default weights (a direct dep is, by default, more load-bearing per-package than any one of the many transitive deps beneath it), but both are paid.

const (
	ScopeDirect     Scope = "direct"
	ScopeTransitive Scope = "transitive"
)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL