New York's OSC chart-of-accounts organizes spending by object (salaries, contractual, equipment) and by function code (1620 buildings, 3120 police, 5110 highway, etc.). It does nottell you what each operational service actually costs to run, fully loaded — because indirect cost centers (employee benefits, buildings, IT, insurance) live in their own function codes and aren't attached to the services they support.
Activity-based costing re-decomposes the same dollars into service activities. Direct lines stay with the service that incurred them. Indirect pools (benefits, overhead) get allocated to operational services using payroll share as the cost driver. The result is one fully-loaded cost per service — police, streets, planning, refuse — that includes its share of shared overhead and benefits.
The pipeline runs the same five steps for every fund in every jurisdiction; only the routing rules differ. Every dollar in the source document ends up somewhere: direct, pooled-and-allocated, or excluded with a documented reason.
For one (jurisdiction, fund, fiscal year, source) document, the allocator does this:
- Direct lines. Every appropriation line is routed to a service via
analysis/abc_routing.yaml. OSC code 3120 (police) goes to police, 5110 (streets) to transportation, 1110 (court) to court, and so on. These stay where they are — no allocation needed. - Benefits pool, allocated by payroll share.OSC 9010-series benefit lines (state retirement, FICA, workers comp, hospital/medical, employee benefit reserve) all pool into a single benefits bucket. Each service's personal-services dollars as a fraction of total fund payroll becomes its share of the pool. If police is 60% of the fund's GF payroll, police gets 60% of the benefits pool.
- Overhead pool, allocated the same way. Indirect general-government lines (1620 buildings, 1640 garage, 1680 IT, 1910 insurance, 1920 municipal dues, restricted-reserve transfers) pool into an overhead bucket, then split by payroll share. The Village FY26-27 case is the exception — see the jurisdiction-specific section below.
- Dedicated revenue offsets the gross.Revenue lines that fund a specific service (Town/Tivoli police-contract payments, refuse-tag sales, zoning fees, court fines, SRO contract, etc.) are subtracted from that service's gross fully-loaded cost.
- General non-tax revenue is distributed proportionally. Revenue not tied to a specific service (state aid, sales-tax distribution from the County, interest earnings, fund-balance draw) is split across services in proportion to their post-dedicated residual cost. What's left is the net levy burden — what the property-tax levy actually has to fund for that service.
appropriation_balanced — sum of direct + pooled + excluded = source appropriation total; revenue_balanced — sum of levy + dedicated + general + excluded revenue = source revenue total; levy_balanced — sum of net-levy-burden across services = the actual levy. If any invariant fails the build halts. Pipeline source: analysis/build_activity_based_cost_allocation.py; routing rules: analysis/abc_routing.yaml.The most recent ABC document for the Village's General Fund (Fund A) is the FY26/27 adopted budget. Top-line totals:
| Total appropriation | $2.65M |
| Total revenue | $2.65M |
| Property-tax levy | $1.47M |
| Total personal-services payroll | $1.13M |
| Benefits pool (allocated by payroll share) | $593K |
| Overhead pool (allocated by payroll share) | $184K |
Per-service buildup, after running the five steps above:
| Service | Direct | Payroll share | Benefits alloc | Overhead alloc | Gross fully-loaded | Dedicated rev | Net levy burden |
|---|---|---|---|---|---|---|---|
| Police | $769,200 | 60.7% | $252,579 | $88,775 | $1,113,054 | −$400,856 | $556,209 |
| Fire protection | $120,305 | — | — | — | $122,805 | — | $95,908 |
| Streets, DPW & lighting | $422,913 | 16.8% | $145,661 | $40,719 | $611,794 | −$50,000 | $438,747 |
| Refuse & sanitation | $81,720 | 3.6% | $30,910 | $8,641 | $121,271 | −$73,039 | $37,668 |
| Planning, zoning & building inspection | $81,000 | 2.4% | $21,161 | $5,915 | $108,076 | −$40,000 | $53,166 |
| Court | $50,500 | 3.6% | $31,548 | $8,819 | $90,868 | −$58,977 | $24,906 |
| Culture & recreation | $8,400 | — | — | — | $8,400 | — | $6,560 |
| Government administration | $292,970 | 12.9% | $111,358 | $31,130 | $437,958 | −$153,300 | $222,311 |
| Debt service | $38,081 | — | — | — | $38,081 | — | $29,740 |
Reconciliation: appropriation balanced — yes; revenue balanced — yes; levy balanced — yes. Source bundle key: red-hook-village/FY26/27/budget_adopted/A.
Drill in: General Fund — FY26/27 drilldown (ABC view) · or browse all years on the General Fund multi-year page.
The Village A General Fund FY 26-27 adopted budget is the one place the pipeline departs from the pure payroll-share default. The bespoke override applies only to that single document — every other Village year, and every Town and Tivoli document, uses pure payroll-share allocation for police along with every other service.
Police bespoke override (Village FY 26-27 only)
Police is 24/7, the primary municipal-liability exposure, and the heaviest IT user in Village government. Pure payroll-share allocation understates police's draw on facility, insurance, and IT overhead. The police_cost_sharing.py analysis computed bespoke shares for the FY 26-27 budget:
- Buildings & utilities (A1620.4 + A1620.41): 35% to police — staffed 24/7, occupies roughly that share of Village Hall floor area.
- Unallocated insurance (A1910.4): 50% to police — primary municipal-liability exposure (use of force, vehicle pursuits, personnel claims).
- Central data processing / IT (A1680.4): 40% to police — heaviest IT user (CAD, evidence management, body cam storage, real-time NCIC/state-system access). Police- specific software is already separately booked under A3120.4x.
- Workers comp (A9040.81): 75% to police — police are the highest-risk Village employees by category.
- Other benefits (retirement, FICA, Medicare, disability): payroll-share allocation, same as every other service.
The residual of each pool after police's bespoke share is split among the remaining services by their payroll share of non-police personnel — so the math still reconciles to the dollar.
The override only applies to FY 26-27 because that's the year police_costs.yaml was extracted against — the specific function-code line amounts in the override are anchored to that budget's published numbers. Future years can be re-extracted the same way; until then they fall back to payroll-share like every other service.
Why the override matters in one number
In the FY 26-27 adopted budget the bespoke shares attribute roughly $89K of overhead to police vs the ~$112K it would absorb under pure 60.7% payroll-share — a smaller overhead number, because the overhead pool sees specific line-by-line splits instead of a single weighted-average ratio. Combined with the bespoke $252,579 benefits figure (which uses the higher 75% workers-comp share), the net effect is well-documented and defensible per-line attribution rather than a single payroll-share blunt instrument.
Sources
- externalABC pipeline: analysis/build_activity_based_cost_allocation.py— The allocator. Reads fiscal_lines.json + abc_routing.yaml + police_sharing.json, emits the per-document bundle.
- externalRouting config: analysis/abc_routing.yaml— OSC function-code → service mapping; revenue routing; police_bespoke_override declaration.
- externalPolice bespoke shares: data/extracts/police_costs.yaml— Source for the 35% facility / 50% insurance / 40% IT shares used to override pure payroll-share allocation for police in the Village FY26-27 adopted budget.
- externalFiscal-lines bundle: site/data/fiscal_lines.json— Pipeline input: every appropriation/revenue line for every (jurisdiction, fund, fy, source) document.
- recordVillage A General Fund — FY 26-27 drilldown (ABC view)— Per-FY drill-down showing each ABC line item with the OSC↔ABC toggle.
- recordVillage A General Fund — multi-year overview— Year-over-year totals; toggle to ABC view to see fully-loaded service trends.
- recordPolice cost-sharing detail— Issue page applying the Village's ABC police number to the inter-municipal contract debate.