fresh-tipsy 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- fresh_tipsy-0.1.0/LICENSE +21 -0
- fresh_tipsy-0.1.0/PKG-INFO +187 -0
- fresh_tipsy-0.1.0/README.md +168 -0
- fresh_tipsy-0.1.0/pyproject.toml +76 -0
- fresh_tipsy-0.1.0/setup.cfg +4 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/__init__.py +7 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/agent/__init__.py +8 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/agent/prompts.py +31 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/agent/tools.py +388 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/api/__init__.py +7 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/api/app.py +191 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/api/models.py +207 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/api/service.py +743 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/cli.py +507 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/curves/__init__.py +50 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/curves/engine.py +335 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/curves/errors.py +27 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/curves/interpolation.py +225 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/curves/metrics.py +303 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/curves/models.py +418 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/curves/validation.py +104 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/economics/__init__.py +56 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/economics/engine.py +434 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/economics/errors.py +23 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/economics/models.py +975 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/integrations/__init__.py +19 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/integrations/femic.py +234 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/products/__init__.py +42 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/products/errors.py +11 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/products/recovery.py +432 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/products/schema.py +329 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/__init__.py +88 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/catalog.py +668 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/columns.py +55 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/data/manifest-schema.json +494 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/data/tab-taf-columns.csv +174 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/errors.py +7 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/formats.py +63 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/manifest.py +221 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/manifest_io.py +312 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/metadata.py +99 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/normalize.py +472 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/tables/parsers.py +850 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/version.py +7 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/__init__.py +7 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/app.py +507 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/static/style.css +148 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/templates/_macros.html +32 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/templates/base.html +26 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/templates/catalog.html +62 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/templates/curve.html +56 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/templates/detail.html +25 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/templates/economics.html +121 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/templates/home.html +30 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy/web/templates/product.html +60 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy.egg-info/PKG-INFO +187 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy.egg-info/SOURCES.txt +97 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy.egg-info/dependency_links.txt +1 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy.egg-info/entry_points.txt +2 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy.egg-info/requires.txt +10 -0
- fresh_tipsy-0.1.0/src/fresh_tipsy.egg-info/top_level.txt +1 -0
- fresh_tipsy-0.1.0/tests/test_agent.py +166 -0
- fresh_tipsy-0.1.0/tests/test_api.py +255 -0
- fresh_tipsy-0.1.0/tests/test_api_docstrings.py +65 -0
- fresh_tipsy-0.1.0/tests/test_catalog.py +157 -0
- fresh_tipsy-0.1.0/tests/test_catalog_errors.py +207 -0
- fresh_tipsy-0.1.0/tests/test_check_workflow.py +809 -0
- fresh_tipsy-0.1.0/tests/test_cli.py +75 -0
- fresh_tipsy-0.1.0/tests/test_cli_db.py +401 -0
- fresh_tipsy-0.1.0/tests/test_cli_interfaces.py +268 -0
- fresh_tipsy-0.1.0/tests/test_curve_golden.py +122 -0
- fresh_tipsy-0.1.0/tests/test_curve_interpolation.py +208 -0
- fresh_tipsy-0.1.0/tests/test_curve_metrics.py +283 -0
- fresh_tipsy-0.1.0/tests/test_curve_properties.py +58 -0
- fresh_tipsy-0.1.0/tests/test_curve_selection.py +273 -0
- fresh_tipsy-0.1.0/tests/test_dashboard.py +217 -0
- fresh_tipsy-0.1.0/tests/test_economics.py +492 -0
- fresh_tipsy-0.1.0/tests/test_femic_integration.py +105 -0
- fresh_tipsy-0.1.0/tests/test_fixtures.py +71 -0
- fresh_tipsy-0.1.0/tests/test_interfaces.py +385 -0
- fresh_tipsy-0.1.0/tests/test_manifest_errors.py +107 -0
- fresh_tipsy-0.1.0/tests/test_manifest_io.py +76 -0
- fresh_tipsy-0.1.0/tests/test_manifest_io_errors.py +160 -0
- fresh_tipsy-0.1.0/tests/test_normalize_errors.py +132 -0
- fresh_tipsy-0.1.0/tests/test_normalized.py +98 -0
- fresh_tipsy-0.1.0/tests/test_package_data.py +31 -0
- fresh_tipsy-0.1.0/tests/test_parser_errors.py +207 -0
- fresh_tipsy-0.1.0/tests/test_product_goldens.py +71 -0
- fresh_tipsy-0.1.0/tests/test_product_recovery.py +229 -0
- fresh_tipsy-0.1.0/tests/test_product_regression.py +56 -0
- fresh_tipsy-0.1.0/tests/test_product_schema.py +88 -0
- fresh_tipsy-0.1.0/tests/test_properties.py +110 -0
- fresh_tipsy-0.1.0/tests/test_properties_tables.py +65 -0
- fresh_tipsy-0.1.0/tests/test_release_assets.py +72 -0
- fresh_tipsy-0.1.0/tests/test_release_golden.py +86 -0
- fresh_tipsy-0.1.0/tests/test_tab_parser.py +128 -0
- fresh_tipsy-0.1.0/tests/test_taf_parser.py +136 -0
- fresh_tipsy-0.1.0/tests/test_web.py +217 -0
- fresh_tipsy-0.1.0/tests/test_workflow.py +19 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 UBC FRESH Lab
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: fresh-tipsy
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A provenance-first Python interoperability layer for BC TIPSY and FAN$IER tables.
|
|
5
|
+
Author: UBC FRESH Lab
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Requires-Python: >=3.11
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: typer>=0.12
|
|
11
|
+
Requires-Dist: jsonschema>=4.20
|
|
12
|
+
Provides-Extra: parquet
|
|
13
|
+
Requires-Dist: pyarrow>=15; extra == "parquet"
|
|
14
|
+
Provides-Extra: api
|
|
15
|
+
Requires-Dist: fastapi>=0.115; extra == "api"
|
|
16
|
+
Requires-Dist: uvicorn>=0.30; extra == "api"
|
|
17
|
+
Requires-Dist: jinja2>=3.1; extra == "api"
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# fresh-tipsy
|
|
21
|
+
|
|
22
|
+
A public, tested Python package for reading TIPSY and FAN$IER data tables,
|
|
23
|
+
exposing growth, product-recovery, and economics workflows, and preserving the
|
|
24
|
+
provenance of every value.
|
|
25
|
+
|
|
26
|
+
`fresh-tipsy` is a reimplementation and interoperability layer. It does not
|
|
27
|
+
claim authorship of TIPSY, FAN$IER, TASS, FEMIC, or BC government data. It exists
|
|
28
|
+
so those models and tables can be queried from Python, tested in the open, and
|
|
29
|
+
used by tools such as FEMIC without a GUI boundary.
|
|
30
|
+
|
|
31
|
+
Repository: <https://github.com/UBC-FRESH/fresh-tipsy>
|
|
32
|
+
|
|
33
|
+
## Status
|
|
34
|
+
|
|
35
|
+
Version 0.1.0 was released on 2026-11-09.
|
|
36
|
+
`ROADMAP.md` and GitHub issues carry the live status. The package is an
|
|
37
|
+
interoperability layer over precomputed TASS/TIPSY tables, not a TASS rewrite.
|
|
38
|
+
|
|
39
|
+
## Features
|
|
40
|
+
|
|
41
|
+
- `.tab`/`.taf` parsers, provenance manifests, catalog, and normalization.
|
|
42
|
+
- Typed growth queries over precomputed TASS/TIPSY tables, with interpolation,
|
|
43
|
+
metrics, source SHA-256, and explicit unavailable metrics.
|
|
44
|
+
- Product recovery for lumber, residues, log grades, graded/degraded lumber, and
|
|
45
|
+
industrial logs, with strict mass-balance checks.
|
|
46
|
+
- Explicit-input product economics: prices, costs, NPV, Faustmann site value,
|
|
47
|
+
and FAN$IER-style sensitivity cases.
|
|
48
|
+
- Typer CLI: `db`, `curve`, `product`, and `econ` commands with JSON output.
|
|
49
|
+
- FastAPI service and Pydantic response envelopes.
|
|
50
|
+
- Server-rendered FRESH-style catalog, curve, product, and economics UI.
|
|
51
|
+
- Deterministic assistant tools with provenance-first prompt guidance.
|
|
52
|
+
- Optional FEMIC adapter with package-version and data-manifest provenance.
|
|
53
|
+
|
|
54
|
+
## What this is not
|
|
55
|
+
|
|
56
|
+
- A claim that UBC-FRESH invented TIPSY, FAN$IER, or FEMIC.
|
|
57
|
+
- A byte-for-byte reimplementation of TASS.
|
|
58
|
+
- A substitute for measured BC log grades or mill-specific recovery.
|
|
59
|
+
- A place to commit raw government data tables, credentials, or personal paths.
|
|
60
|
+
- A validated FAN$IER replacement.
|
|
61
|
+
|
|
62
|
+
## Install
|
|
63
|
+
|
|
64
|
+
From a source checkout:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
python -m venv .venv
|
|
68
|
+
. .venv/bin/activate
|
|
69
|
+
python -m pip install -e ".[api,parquet]"
|
|
70
|
+
python scripts/dashboard.py
|
|
71
|
+
fresh-tipsy --help
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Extras:
|
|
75
|
+
|
|
76
|
+
- `api`: FastAPI, Jinja2, and uvicorn for the HTTP API and web UI.
|
|
77
|
+
- `parquet`: PyArrow for Parquet normalization and `db extract`.
|
|
78
|
+
- The minimal install supports parsing, catalog, curve, product, and economics
|
|
79
|
+
commands that do not need Parquet or the API.
|
|
80
|
+
|
|
81
|
+
Download the wheel, sdist, or HTML docs archive from the 0.1.0 GitHub release.
|
|
82
|
+
Build evidence is in [`notes/reference/package-build.md`](notes/reference/package-build.md).
|
|
83
|
+
|
|
84
|
+
## Quick start
|
|
85
|
+
|
|
86
|
+
Set the local source roots:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
export TIPSY_INSTALL="/path/to/tipsy"
|
|
90
|
+
export TIPSY_DATABASE="$TIPSY_INSTALL/Database"
|
|
91
|
+
export FRESH_TIPSY_CACHE="/path/to/fresh-tipsy-cache"
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Extract a catalog from a local licensed install:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
fresh-tipsy db extract --source "$TIPSY_INSTALL" --out "$FRESH_TIPSY_CACHE"
|
|
98
|
+
fresh-tipsy db validate --catalog "$FRESH_TIPSY_CACHE/manifest.json" --source "$TIPSY_INSTALL"
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Query growth, products, and economics:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
fresh-tipsy curve query --catalog "$FRESH_TIPSY_CACHE/manifest.json" \
|
|
105
|
+
--source "$TIPSY_INSTALL" --species PLI --site-index 20 --age 80 --pnc N --json
|
|
106
|
+
|
|
107
|
+
fresh-tipsy product recover --catalog "$FRESH_TIPSY_CACHE/manifest.json" \
|
|
108
|
+
--source "$TIPSY_INSTALL" --species PLI --site-index 20 --age 80 --pnc N --json
|
|
109
|
+
|
|
110
|
+
fresh-tipsy econ run --catalog "$FRESH_TIPSY_CACHE/manifest.json" \
|
|
111
|
+
--source "$TIPSY_INSTALL" --scenario scenario.json --json
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
The scenario schema and exit codes are in
|
|
115
|
+
[`notes/reference/cli.md`](notes/reference/cli.md). The API and web UI are in
|
|
116
|
+
[`notes/reference/api.md`](notes/reference/api.md) and
|
|
117
|
+
[`notes/reference/web.md`](notes/reference/web.md).
|
|
118
|
+
|
|
119
|
+
## Validation and evidence
|
|
120
|
+
|
|
121
|
+
- Four-species TIPSY golden regression: PLI, FDC, AT, and FDI exact ages plus
|
|
122
|
+
product mass balance. See
|
|
123
|
+
[`notes/reference/release-validation.md`](notes/reference/release-validation.md).
|
|
124
|
+
- Hand-checked economics case: NPV 335.543289 CAD/ha and site value 546.081251
|
|
125
|
+
CAD/ha for the documented inputs. See
|
|
126
|
+
[`notes/reference/economics.md`](notes/reference/economics.md).
|
|
127
|
+
- Cross-interface parity for CLI, API, web, and assistant tools.
|
|
128
|
+
- 376 tests passed and 13 skipped at the last preparation run; combined branch
|
|
129
|
+
coverage 95.5%.
|
|
130
|
+
- Real-source tests skip when `TIPSY_DATABASE` is unset; a skip is not a pass.
|
|
131
|
+
|
|
132
|
+
## Known gaps
|
|
133
|
+
|
|
134
|
+
The release is deliberately explicit about missing evidence:
|
|
135
|
+
|
|
136
|
+
- TIPSY custom runtime output is unavailable under Wine.
|
|
137
|
+
- FAN$IER price, cost, product-suite, and NPV tables are unparsed.
|
|
138
|
+
- FEMIC TSR output is not captured.
|
|
139
|
+
- Product aggregate totals are not stored in `.taf`; aggregate checks are
|
|
140
|
+
derived, with an independent #2 & Better-to-graded cross-check.
|
|
141
|
+
- Residue totals are absent.
|
|
142
|
+
- Carbon conversion is unavailable.
|
|
143
|
+
- No measured BC field grade or mill-specific recovery is claimed.
|
|
144
|
+
- FEMIC adapter call and dependency are prepared but not applied to the FEMIC
|
|
145
|
+
repository.
|
|
146
|
+
- Wheel/sdist are prepared but not published.
|
|
147
|
+
|
|
148
|
+
See [`notes/reference/known-gaps.md`](notes/reference/known-gaps.md) for the full
|
|
149
|
+
list and limits.
|
|
150
|
+
|
|
151
|
+
## Citation
|
|
152
|
+
|
|
153
|
+
Cite the package, the source model, and the specific table path and SHA-256.
|
|
154
|
+
Raw data is not relicensed by this package.
|
|
155
|
+
|
|
156
|
+
- [`CITATION.cff`](CITATION.cff)
|
|
157
|
+
- [`notes/reference/citation.md`](notes/reference/citation.md)
|
|
158
|
+
- [`notes/reference/source-inventory.md`](notes/reference/source-inventory.md)
|
|
159
|
+
|
|
160
|
+
## Release notes
|
|
161
|
+
|
|
162
|
+
- [`RELEASE_NOTES.md`](RELEASE_NOTES.md)
|
|
163
|
+
- [`notes/reference/release-assets.md`](notes/reference/release-assets.md)
|
|
164
|
+
- [`notes/reference/release-assets.csv`](notes/reference/release-assets.csv)
|
|
165
|
+
|
|
166
|
+
## Repository map
|
|
167
|
+
|
|
168
|
+
| Path | Purpose |
|
|
169
|
+
| --- | --- |
|
|
170
|
+
| `AGENTS.md` | Operating contract for coding agents |
|
|
171
|
+
| `HANDOFF.md` | First-read handoff note for a new session agent |
|
|
172
|
+
| `ROADMAP.md` | Plan of record and issue tracker map |
|
|
173
|
+
| `CHANGE_LOG.md` | Dated narrative of changes |
|
|
174
|
+
| `RELEASE_NOTES.md` | 0.1.0 release notes and known gaps |
|
|
175
|
+
| `notes/plan/` | Program, data, architecture, and validation plans |
|
|
176
|
+
| `notes/reference/` | Source inventory, schemas, validation, and release facts |
|
|
177
|
+
| `notes/adr/` | Accepted design decisions |
|
|
178
|
+
| `docs/` | Sphinx RTFM surface |
|
|
179
|
+
| `scripts/check_workflow.py` | Workflow validator |
|
|
180
|
+
| `scripts/check_release_assets.py` | Release asset and checksum validator |
|
|
181
|
+
| `tests/` | pytest suite, including interface and release checks |
|
|
182
|
+
|
|
183
|
+
## License and attribution
|
|
184
|
+
|
|
185
|
+
Code is MIT licensed. Data tables and model outputs retain their original BC
|
|
186
|
+
government attribution. Cite the source model and table, not only this package.
|
|
187
|
+
No source table, normalized asset, or model output is relicensed here.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# fresh-tipsy
|
|
2
|
+
|
|
3
|
+
A public, tested Python package for reading TIPSY and FAN$IER data tables,
|
|
4
|
+
exposing growth, product-recovery, and economics workflows, and preserving the
|
|
5
|
+
provenance of every value.
|
|
6
|
+
|
|
7
|
+
`fresh-tipsy` is a reimplementation and interoperability layer. It does not
|
|
8
|
+
claim authorship of TIPSY, FAN$IER, TASS, FEMIC, or BC government data. It exists
|
|
9
|
+
so those models and tables can be queried from Python, tested in the open, and
|
|
10
|
+
used by tools such as FEMIC without a GUI boundary.
|
|
11
|
+
|
|
12
|
+
Repository: <https://github.com/UBC-FRESH/fresh-tipsy>
|
|
13
|
+
|
|
14
|
+
## Status
|
|
15
|
+
|
|
16
|
+
Version 0.1.0 was released on 2026-11-09.
|
|
17
|
+
`ROADMAP.md` and GitHub issues carry the live status. The package is an
|
|
18
|
+
interoperability layer over precomputed TASS/TIPSY tables, not a TASS rewrite.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- `.tab`/`.taf` parsers, provenance manifests, catalog, and normalization.
|
|
23
|
+
- Typed growth queries over precomputed TASS/TIPSY tables, with interpolation,
|
|
24
|
+
metrics, source SHA-256, and explicit unavailable metrics.
|
|
25
|
+
- Product recovery for lumber, residues, log grades, graded/degraded lumber, and
|
|
26
|
+
industrial logs, with strict mass-balance checks.
|
|
27
|
+
- Explicit-input product economics: prices, costs, NPV, Faustmann site value,
|
|
28
|
+
and FAN$IER-style sensitivity cases.
|
|
29
|
+
- Typer CLI: `db`, `curve`, `product`, and `econ` commands with JSON output.
|
|
30
|
+
- FastAPI service and Pydantic response envelopes.
|
|
31
|
+
- Server-rendered FRESH-style catalog, curve, product, and economics UI.
|
|
32
|
+
- Deterministic assistant tools with provenance-first prompt guidance.
|
|
33
|
+
- Optional FEMIC adapter with package-version and data-manifest provenance.
|
|
34
|
+
|
|
35
|
+
## What this is not
|
|
36
|
+
|
|
37
|
+
- A claim that UBC-FRESH invented TIPSY, FAN$IER, or FEMIC.
|
|
38
|
+
- A byte-for-byte reimplementation of TASS.
|
|
39
|
+
- A substitute for measured BC log grades or mill-specific recovery.
|
|
40
|
+
- A place to commit raw government data tables, credentials, or personal paths.
|
|
41
|
+
- A validated FAN$IER replacement.
|
|
42
|
+
|
|
43
|
+
## Install
|
|
44
|
+
|
|
45
|
+
From a source checkout:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
python -m venv .venv
|
|
49
|
+
. .venv/bin/activate
|
|
50
|
+
python -m pip install -e ".[api,parquet]"
|
|
51
|
+
python scripts/dashboard.py
|
|
52
|
+
fresh-tipsy --help
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Extras:
|
|
56
|
+
|
|
57
|
+
- `api`: FastAPI, Jinja2, and uvicorn for the HTTP API and web UI.
|
|
58
|
+
- `parquet`: PyArrow for Parquet normalization and `db extract`.
|
|
59
|
+
- The minimal install supports parsing, catalog, curve, product, and economics
|
|
60
|
+
commands that do not need Parquet or the API.
|
|
61
|
+
|
|
62
|
+
Download the wheel, sdist, or HTML docs archive from the 0.1.0 GitHub release.
|
|
63
|
+
Build evidence is in [`notes/reference/package-build.md`](notes/reference/package-build.md).
|
|
64
|
+
|
|
65
|
+
## Quick start
|
|
66
|
+
|
|
67
|
+
Set the local source roots:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
export TIPSY_INSTALL="/path/to/tipsy"
|
|
71
|
+
export TIPSY_DATABASE="$TIPSY_INSTALL/Database"
|
|
72
|
+
export FRESH_TIPSY_CACHE="/path/to/fresh-tipsy-cache"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Extract a catalog from a local licensed install:
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
fresh-tipsy db extract --source "$TIPSY_INSTALL" --out "$FRESH_TIPSY_CACHE"
|
|
79
|
+
fresh-tipsy db validate --catalog "$FRESH_TIPSY_CACHE/manifest.json" --source "$TIPSY_INSTALL"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Query growth, products, and economics:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
fresh-tipsy curve query --catalog "$FRESH_TIPSY_CACHE/manifest.json" \
|
|
86
|
+
--source "$TIPSY_INSTALL" --species PLI --site-index 20 --age 80 --pnc N --json
|
|
87
|
+
|
|
88
|
+
fresh-tipsy product recover --catalog "$FRESH_TIPSY_CACHE/manifest.json" \
|
|
89
|
+
--source "$TIPSY_INSTALL" --species PLI --site-index 20 --age 80 --pnc N --json
|
|
90
|
+
|
|
91
|
+
fresh-tipsy econ run --catalog "$FRESH_TIPSY_CACHE/manifest.json" \
|
|
92
|
+
--source "$TIPSY_INSTALL" --scenario scenario.json --json
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The scenario schema and exit codes are in
|
|
96
|
+
[`notes/reference/cli.md`](notes/reference/cli.md). The API and web UI are in
|
|
97
|
+
[`notes/reference/api.md`](notes/reference/api.md) and
|
|
98
|
+
[`notes/reference/web.md`](notes/reference/web.md).
|
|
99
|
+
|
|
100
|
+
## Validation and evidence
|
|
101
|
+
|
|
102
|
+
- Four-species TIPSY golden regression: PLI, FDC, AT, and FDI exact ages plus
|
|
103
|
+
product mass balance. See
|
|
104
|
+
[`notes/reference/release-validation.md`](notes/reference/release-validation.md).
|
|
105
|
+
- Hand-checked economics case: NPV 335.543289 CAD/ha and site value 546.081251
|
|
106
|
+
CAD/ha for the documented inputs. See
|
|
107
|
+
[`notes/reference/economics.md`](notes/reference/economics.md).
|
|
108
|
+
- Cross-interface parity for CLI, API, web, and assistant tools.
|
|
109
|
+
- 376 tests passed and 13 skipped at the last preparation run; combined branch
|
|
110
|
+
coverage 95.5%.
|
|
111
|
+
- Real-source tests skip when `TIPSY_DATABASE` is unset; a skip is not a pass.
|
|
112
|
+
|
|
113
|
+
## Known gaps
|
|
114
|
+
|
|
115
|
+
The release is deliberately explicit about missing evidence:
|
|
116
|
+
|
|
117
|
+
- TIPSY custom runtime output is unavailable under Wine.
|
|
118
|
+
- FAN$IER price, cost, product-suite, and NPV tables are unparsed.
|
|
119
|
+
- FEMIC TSR output is not captured.
|
|
120
|
+
- Product aggregate totals are not stored in `.taf`; aggregate checks are
|
|
121
|
+
derived, with an independent #2 & Better-to-graded cross-check.
|
|
122
|
+
- Residue totals are absent.
|
|
123
|
+
- Carbon conversion is unavailable.
|
|
124
|
+
- No measured BC field grade or mill-specific recovery is claimed.
|
|
125
|
+
- FEMIC adapter call and dependency are prepared but not applied to the FEMIC
|
|
126
|
+
repository.
|
|
127
|
+
- Wheel/sdist are prepared but not published.
|
|
128
|
+
|
|
129
|
+
See [`notes/reference/known-gaps.md`](notes/reference/known-gaps.md) for the full
|
|
130
|
+
list and limits.
|
|
131
|
+
|
|
132
|
+
## Citation
|
|
133
|
+
|
|
134
|
+
Cite the package, the source model, and the specific table path and SHA-256.
|
|
135
|
+
Raw data is not relicensed by this package.
|
|
136
|
+
|
|
137
|
+
- [`CITATION.cff`](CITATION.cff)
|
|
138
|
+
- [`notes/reference/citation.md`](notes/reference/citation.md)
|
|
139
|
+
- [`notes/reference/source-inventory.md`](notes/reference/source-inventory.md)
|
|
140
|
+
|
|
141
|
+
## Release notes
|
|
142
|
+
|
|
143
|
+
- [`RELEASE_NOTES.md`](RELEASE_NOTES.md)
|
|
144
|
+
- [`notes/reference/release-assets.md`](notes/reference/release-assets.md)
|
|
145
|
+
- [`notes/reference/release-assets.csv`](notes/reference/release-assets.csv)
|
|
146
|
+
|
|
147
|
+
## Repository map
|
|
148
|
+
|
|
149
|
+
| Path | Purpose |
|
|
150
|
+
| --- | --- |
|
|
151
|
+
| `AGENTS.md` | Operating contract for coding agents |
|
|
152
|
+
| `HANDOFF.md` | First-read handoff note for a new session agent |
|
|
153
|
+
| `ROADMAP.md` | Plan of record and issue tracker map |
|
|
154
|
+
| `CHANGE_LOG.md` | Dated narrative of changes |
|
|
155
|
+
| `RELEASE_NOTES.md` | 0.1.0 release notes and known gaps |
|
|
156
|
+
| `notes/plan/` | Program, data, architecture, and validation plans |
|
|
157
|
+
| `notes/reference/` | Source inventory, schemas, validation, and release facts |
|
|
158
|
+
| `notes/adr/` | Accepted design decisions |
|
|
159
|
+
| `docs/` | Sphinx RTFM surface |
|
|
160
|
+
| `scripts/check_workflow.py` | Workflow validator |
|
|
161
|
+
| `scripts/check_release_assets.py` | Release asset and checksum validator |
|
|
162
|
+
| `tests/` | pytest suite, including interface and release checks |
|
|
163
|
+
|
|
164
|
+
## License and attribution
|
|
165
|
+
|
|
166
|
+
Code is MIT licensed. Data tables and model outputs retain their original BC
|
|
167
|
+
government attribution. Cite the source model and table, not only this package.
|
|
168
|
+
No source table, normalized asset, or model output is relicensed here.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Tool configuration for the UBC-FRESH dev workflow and the fresh-tipsy package.
|
|
2
|
+
# Each gate configured here is also a check in the green dashboard
|
|
3
|
+
# (scripts/dashboard.py).
|
|
4
|
+
|
|
5
|
+
[build-system]
|
|
6
|
+
requires = ["setuptools>=68"]
|
|
7
|
+
build-backend = "setuptools.build_meta"
|
|
8
|
+
|
|
9
|
+
[project]
|
|
10
|
+
name = "fresh-tipsy"
|
|
11
|
+
version = "0.1.0"
|
|
12
|
+
description = "A provenance-first Python interoperability layer for BC TIPSY and FAN$IER tables."
|
|
13
|
+
readme = "README.md"
|
|
14
|
+
requires-python = ">=3.11"
|
|
15
|
+
license = "MIT"
|
|
16
|
+
authors = [{ name = "UBC FRESH Lab" }]
|
|
17
|
+
dependencies = ["typer>=0.12", "jsonschema>=4.20"]
|
|
18
|
+
|
|
19
|
+
[project.optional-dependencies]
|
|
20
|
+
parquet = ["pyarrow>=15"]
|
|
21
|
+
api = ["fastapi>=0.115", "uvicorn>=0.30", "jinja2>=3.1"]
|
|
22
|
+
|
|
23
|
+
[project.scripts]
|
|
24
|
+
fresh-tipsy = "fresh_tipsy.cli:main"
|
|
25
|
+
|
|
26
|
+
[tool.setuptools.packages.find]
|
|
27
|
+
where = ["src"]
|
|
28
|
+
|
|
29
|
+
[tool.setuptools.package-data]
|
|
30
|
+
"fresh_tipsy.tables" = ["data/*.csv", "data/*.json"]
|
|
31
|
+
"fresh_tipsy.web" = ["templates/*.html", "static/*.css"]
|
|
32
|
+
|
|
33
|
+
[tool.ruff]
|
|
34
|
+
line-length = 100
|
|
35
|
+
target-version = "py311"
|
|
36
|
+
src = ["scripts", "tests", "src"]
|
|
37
|
+
extend-exclude = ["tmp", "_build"]
|
|
38
|
+
|
|
39
|
+
[tool.ruff.lint]
|
|
40
|
+
select = ["E", "W", "F", "I", "B", "UP", "D", "ANN", "N", "PT", "SIM", "RUF", "C4"]
|
|
41
|
+
|
|
42
|
+
[tool.ruff.lint.pydocstyle]
|
|
43
|
+
convention = "numpy"
|
|
44
|
+
|
|
45
|
+
[tool.ruff.lint.per-file-ignores]
|
|
46
|
+
"tests/**" = ["D"]
|
|
47
|
+
"templates/project/tests/**" = ["D"]
|
|
48
|
+
"docs/conf.py" = ["D", "ANN", "N"]
|
|
49
|
+
|
|
50
|
+
[tool.mypy]
|
|
51
|
+
python_version = "3.11"
|
|
52
|
+
strict = true
|
|
53
|
+
warn_unreachable = true
|
|
54
|
+
mypy_path = "scripts"
|
|
55
|
+
files = ["scripts", "src", "tests", "docs/conf.py"]
|
|
56
|
+
|
|
57
|
+
[[tool.mypy.overrides]]
|
|
58
|
+
module = ["numpydoc", "numpydoc.*"]
|
|
59
|
+
ignore_missing_imports = true
|
|
60
|
+
|
|
61
|
+
[[tool.mypy.overrides]]
|
|
62
|
+
module = ["pyarrow", "pyarrow.*"]
|
|
63
|
+
ignore_missing_imports = true
|
|
64
|
+
|
|
65
|
+
[tool.pytest.ini_options]
|
|
66
|
+
testpaths = ["tests"]
|
|
67
|
+
pythonpath = ["src"]
|
|
68
|
+
addopts = "--cov=scripts --cov=src/fresh_tipsy --cov-branch --cov-report=term-missing --cov-fail-under=95"
|
|
69
|
+
|
|
70
|
+
[tool.coverage.run]
|
|
71
|
+
branch = true
|
|
72
|
+
source = ["scripts", "src/fresh_tipsy"]
|
|
73
|
+
|
|
74
|
+
[tool.coverage.report]
|
|
75
|
+
show_missing = true
|
|
76
|
+
exclude_also = ['if __name__ == "__main__":']
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"""Bounded assistant tools and prompt guidance."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from fresh_tipsy.agent.prompts import SYSTEM_PROMPT, prompt
|
|
6
|
+
from fresh_tipsy.agent.tools import ToolBox, ToolResult, tool_specs
|
|
7
|
+
|
|
8
|
+
__all__ = ["SYSTEM_PROMPT", "ToolBox", "ToolResult", "prompt", "tool_specs"]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"""Provenance-first prompt guidance for an optional assistant adapter."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
SYSTEM_PROMPT = """You are a bounded assistant for fresh-tipsy, a provenance-first
|
|
6
|
+
interoperability layer for BC TIPSY and FAN$IER data.
|
|
7
|
+
|
|
8
|
+
Rules:
|
|
9
|
+
- Use the provided tools. Never invent a table, column, coefficient, price, cost,
|
|
10
|
+
grade, or result.
|
|
11
|
+
- Every answer must identify the source table or asset and the original query
|
|
12
|
+
inputs. If provenance is missing, say so and stop.
|
|
13
|
+
- Product values are TASS/SYLVER model output, not measured BC field grades.
|
|
14
|
+
- Economics is reimplemented from documented formulas with explicit inputs and
|
|
15
|
+
is not validated against FAN$IER. Missing prices and incompatible units are
|
|
16
|
+
gaps, not zero.
|
|
17
|
+
- If a tool returns an error or warning, report it instead of guessing.
|
|
18
|
+
- Do not claim mill-specific recovery or a measured grade.
|
|
19
|
+
- Keep raw data out of the answer; cite the source path and checksum."
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def prompt() -> str:
|
|
24
|
+
"""Return the provenance-first system prompt.
|
|
25
|
+
|
|
26
|
+
Returns
|
|
27
|
+
-------
|
|
28
|
+
str
|
|
29
|
+
System prompt.
|
|
30
|
+
"""
|
|
31
|
+
return SYSTEM_PROMPT
|