kairopsis 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.
- kairopsis-0.1.0/.python-version +1 -0
- kairopsis-0.1.0/AGENTS.md +16 -0
- kairopsis-0.1.0/CONTEXT.md +78 -0
- kairopsis-0.1.0/PKG-INFO +47 -0
- kairopsis-0.1.0/README.md +27 -0
- kairopsis-0.1.0/docs/adr/0001-public-wheel-distribution.md +10 -0
- kairopsis-0.1.0/docs/adr/0002-local-user-deployment.md +8 -0
- kairopsis-0.1.0/docs/adr/0003-metapyle-data-access.md +10 -0
- kairopsis-0.1.0/docs/adr/0004-portable-idea-evidence.md +11 -0
- kairopsis-0.1.0/docs/agents/domain.md +27 -0
- kairopsis-0.1.0/docs/agents/issue-tracker.md +40 -0
- kairopsis-0.1.0/docs/agents/triage-labels.md +14 -0
- kairopsis-0.1.0/docs/risk-adjustment.md +45 -0
- kairopsis-0.1.0/docs/runtime.md +72 -0
- kairopsis-0.1.0/docs/verification.md +52 -0
- kairopsis-0.1.0/pyproject.toml +51 -0
- kairopsis-0.1.0/pyproject.toml.orig +42 -0
- kairopsis-0.1.0/scripts/acceptance/inspect_wheel.py +105 -0
- kairopsis-0.1.0/scripts/acceptance/loopback_guard/sitecustomize.py +54 -0
- kairopsis-0.1.0/scripts/acceptance/run_windows.py +124 -0
- kairopsis-0.1.0/scripts/browser_acceptance.py +231 -0
- kairopsis-0.1.0/scripts/browser_chart_layout.py +78 -0
- kairopsis-0.1.0/scripts/browser_copy_data.py +133 -0
- kairopsis-0.1.0/scripts/browser_evidence_copy.py +91 -0
- kairopsis-0.1.0/scripts/vendor_assets.py +38 -0
- kairopsis-0.1.0/src/kairopsis/__init__.py +20 -0
- kairopsis-0.1.0/src/kairopsis/analytics.py +160 -0
- kairopsis-0.1.0/src/kairopsis/app.py +235 -0
- kairopsis-0.1.0/src/kairopsis/catalogue.py +93 -0
- kairopsis-0.1.0/src/kairopsis/config.py +74 -0
- kairopsis-0.1.0/src/kairopsis/docs/agent-setup.md +154 -0
- kairopsis-0.1.0/src/kairopsis/docs/human-guide.md +93 -0
- kairopsis-0.1.0/src/kairopsis/evaluation_comparison.py +65 -0
- kairopsis-0.1.0/src/kairopsis/fixtures.py +72 -0
- kairopsis-0.1.0/src/kairopsis/frequencies.py +27 -0
- kairopsis-0.1.0/src/kairopsis/live_config.py +46 -0
- kairopsis-0.1.0/src/kairopsis/metapyle_adapter.py +148 -0
- kairopsis-0.1.0/src/kairopsis/metapyle_catalogue.py +62 -0
- kairopsis-0.1.0/src/kairopsis/models.py +292 -0
- kairopsis-0.1.0/src/kairopsis/repository.py +221 -0
- kairopsis-0.1.0/src/kairopsis/risk.py +130 -0
- kairopsis-0.1.0/src/kairopsis/service.py +141 -0
- kairopsis-0.1.0/src/kairopsis/static/charts.js +421 -0
- kairopsis-0.1.0/src/kairopsis/static/icon.svg +1 -0
- kairopsis-0.1.0/src/kairopsis/static/research.css +650 -0
- kairopsis-0.1.0/src/kairopsis/static/research.js +809 -0
- kairopsis-0.1.0/src/kairopsis/static/vendor/AG-GRID-LICENSE.txt +21 -0
- kairopsis-0.1.0/src/kairopsis/static/vendor/PLOTLY-LICENSE.txt +21 -0
- kairopsis-0.1.0/src/kairopsis/static/vendor/ag-grid-community.min.js +1 -0
- kairopsis-0.1.0/src/kairopsis/static/vendor/ag-grid.css +7029 -0
- kairopsis-0.1.0/src/kairopsis/static/vendor/ag-theme-quartz.css +1187 -0
- kairopsis-0.1.0/src/kairopsis/static/vendor/manifest.json +44 -0
- kairopsis-0.1.0/src/kairopsis/static/vendor/plotly.min.js +3882 -0
- kairopsis-0.1.0/src/kairopsis/templates/app.html +19 -0
- kairopsis-0.1.0/tests/.pytest_cache/.gitignore +2 -0
- kairopsis-0.1.0/tests/.pytest_cache/CACHEDIR.TAG +4 -0
- kairopsis-0.1.0/tests/.pytest_cache/README.md +8 -0
- kairopsis-0.1.0/tests/.pytest_cache/v/cache/nodeids +31 -0
- kairopsis-0.1.0/tests/test_metapyle_adapter.py +176 -0
- kairopsis-0.1.0/tests/test_metapyle_catalogue.py +163 -0
- kairopsis-0.1.0/tests/test_rebuild_analytics.py +94 -0
- kairopsis-0.1.0/tests/test_rebuild_http.py +205 -0
- kairopsis-0.1.0/tests/test_rebuild_refresh.py +80 -0
- kairopsis-0.1.0/tests/test_rebuild_storage.py +43 -0
- kairopsis-0.1.0/tests/test_risk_adjustment.py +168 -0
- kairopsis-0.1.0/uv.lock +2076 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
3.12
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Agent skills
|
|
2
|
+
|
|
3
|
+
### Issue tracker
|
|
4
|
+
|
|
5
|
+
Issues live as local Markdown under `.scratch/`. Before creating,
|
|
6
|
+
reading, or updating tickets, read `docs/agents/issue-tracker.md`.
|
|
7
|
+
|
|
8
|
+
### Triage labels
|
|
9
|
+
|
|
10
|
+
Use the five default triage roles. Before triaging issues, read
|
|
11
|
+
`docs/agents/triage-labels.md`.
|
|
12
|
+
|
|
13
|
+
### Domain docs
|
|
14
|
+
|
|
15
|
+
Use a single-context layout: root `CONTEXT.md` and `docs/adr/`.
|
|
16
|
+
Before exploring the codebase, read `docs/agents/domain.md`.
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Kairopsis
|
|
2
|
+
|
|
3
|
+
Kairopsis supports relative-value investigation and the development of investment views for team discussion.
|
|
4
|
+
|
|
5
|
+
## Language
|
|
6
|
+
|
|
7
|
+
**Relative Value Relationship**:
|
|
8
|
+
An economically meaningful comparison between sectors, segments, or exposures whose pricing is examined for relative attractiveness, including credit exposures relative to rates and FX.
|
|
9
|
+
|
|
10
|
+
**Relationship Family**:
|
|
11
|
+
A set of Relative Value Relationships that share an explicit economic rationale for comparison.
|
|
12
|
+
Comparisons between credit exposures in different currencies remain credit-credit relationships.
|
|
13
|
+
|
|
14
|
+
**Cross-Market Inconsistency**:
|
|
15
|
+
A difference in the economic implications of pricing across markets under a stated interpretation, even when no clear trade expression has been identified.
|
|
16
|
+
|
|
17
|
+
**Comparison Basis**:
|
|
18
|
+
The currency and reference-curve conventions underlying a metric, including any rebasing applied to make it comparable across markets.
|
|
19
|
+
|
|
20
|
+
**Flag**:
|
|
21
|
+
An observed condition or change in a single asset or a Relative Value Relationship that merits investigation, with an identifiable reason for drawing attention to it. Flags include extreme historical percentiles and significant changes in asset measures or pairwise ratios, differences, and regression residuals.
|
|
22
|
+
_Avoid_: Investment recommendation
|
|
23
|
+
|
|
24
|
+
**Economic Materiality**:
|
|
25
|
+
The significance of an observed level or change to an investment argument, judged using measures appropriate to its Relationship Family.
|
|
26
|
+
|
|
27
|
+
**Catch-up**:
|
|
28
|
+
A retrospective examination of the most significant market and relationship changes over a user-selected period.
|
|
29
|
+
_Avoid_: Unread alert backlog
|
|
30
|
+
|
|
31
|
+
**Relative Value View**:
|
|
32
|
+
An investment judgment about the attractiveness of one sector, segment, or exposure relative to another, supported by evidence and an economic argument.
|
|
33
|
+
_Avoid_: Signal when an investment judgment is meant
|
|
34
|
+
|
|
35
|
+
**Possible Expression**:
|
|
36
|
+
A proposed way to express a Relative Value View through market exposures, without account-specific sizing or suitability analysis.
|
|
37
|
+
_Avoid_: Account Expression
|
|
38
|
+
|
|
39
|
+
**Idea**:
|
|
40
|
+
A saved investigation that develops and revisits a Relative Value View, collecting supporting and challenging evidence, arguments, and possible expressions.
|
|
41
|
+
_Avoid_: Individual flag or chart when referring to the whole investigation
|
|
42
|
+
|
|
43
|
+
**Research Asset**:
|
|
44
|
+
A chart, snapshot, note, argument, or narrative retained as part of an Idea.
|
|
45
|
+
|
|
46
|
+
**Snapshot**:
|
|
47
|
+
A frozen record of chart evidence at a particular time, including the underlying observations, analytical choices, and Comparison Basis.
|
|
48
|
+
_Avoid_: Live chart
|
|
49
|
+
|
|
50
|
+
**Research Pack**:
|
|
51
|
+
A selection of an Idea's evidence and arguments assembled to support narrative drafting outside Kairopsis.
|
|
52
|
+
_Avoid_: Standardized report for team distribution
|
|
53
|
+
|
|
54
|
+
**Discussion Shortlist**:
|
|
55
|
+
The Ideas selected for upcoming team conversations or meetings, independently of their investigation state.
|
|
56
|
+
|
|
57
|
+
**Revisit Condition**:
|
|
58
|
+
A stated condition whose fulfillment warrants renewed attention to an Idea.
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
**Data Series**:
|
|
62
|
+
A time-ordered set of observations for a particular asset measure, with an identified source, units and Comparison Basis.
|
|
63
|
+
|
|
64
|
+
**Analysis**:
|
|
65
|
+
A defined investigation of one or two Data Series, including its calculation and analytical settings. Its type is Standalone or Pair.
|
|
66
|
+
|
|
67
|
+
**Risk Adjustment**:
|
|
68
|
+
An adjustment of spread changes or returns using an estimated risk measure or sensitivity to support comparison between exposures.
|
|
69
|
+
|
|
70
|
+
**Frequency**:
|
|
71
|
+
The daily, weekly or monthly interval over which an Analysis measures changes or returns. Risk Adjustment estimates use the same interval.
|
|
72
|
+
_Avoid_: Measurement horizon
|
|
73
|
+
|
|
74
|
+
**Standalone**:
|
|
75
|
+
An Analysis of one Data Series, examining its level or changes relative to its history.
|
|
76
|
+
|
|
77
|
+
**Pair**:
|
|
78
|
+
An Analysis relating two specified Data Series through a ratio, difference or regression.
|
kairopsis-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: kairopsis
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Relative-value idea generation dashboard powered by metapyle
|
|
5
|
+
Author: Stabile Frisur
|
|
6
|
+
Author-email: Stabile Frisur <26568863+stabilefrisur@users.noreply.github.com>
|
|
7
|
+
Requires-Dist: fastapi==0.135.2
|
|
8
|
+
Requires-Dist: jinja2==3.1.6
|
|
9
|
+
Requires-Dist: metapyle>=0.1.6
|
|
10
|
+
Requires-Dist: pandas==3.0.6
|
|
11
|
+
Requires-Dist: platformdirs==4.5.1
|
|
12
|
+
Requires-Dist: pydantic==2.13.5
|
|
13
|
+
Requires-Dist: tzdata==2026.4
|
|
14
|
+
Requires-Dist: uvicorn==0.42.0
|
|
15
|
+
Requires-Python: >=3.12
|
|
16
|
+
Project-URL: Repository, https://github.com/stabilefrisur/kairopsis
|
|
17
|
+
Project-URL: Documentation, https://github.com/stabilefrisur/kairopsis/blob/main/src/kairopsis/docs/human-guide.md
|
|
18
|
+
Project-URL: Issues, https://github.com/stabilefrisur/kairopsis/issues
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
|
|
21
|
+
# Kairopsis
|
|
22
|
+
|
|
23
|
+
A local workspace for relative-value research.
|
|
24
|
+
|
|
25
|
+
Explore market series, compare exposures, and develop investment Ideas with
|
|
26
|
+
charts and notes you can revisit. Kairopsis brings investigation and saved
|
|
27
|
+
evidence together in a browser-based dashboard.
|
|
28
|
+
|
|
29
|
+
- **Investigate:** levels, differences, ratios and regression residuals, with
|
|
30
|
+
historical context and optional risk adjustment.
|
|
31
|
+
- **Retain evidence:** save charts, observations and notes alongside each Idea.
|
|
32
|
+
- **Revisit and share:** compare saved evidence with the latest data and export
|
|
33
|
+
charts or spreadsheet-ready values.
|
|
34
|
+
|
|
35
|
+
A built-in demo lets you explore without market-data credentials. Your research
|
|
36
|
+
stays in a local workspace. Live data access uses Metapyle.
|
|
37
|
+
|
|
38
|
+
## Guides
|
|
39
|
+
|
|
40
|
+
- [Human guide](https://github.com/stabilefrisur/kairopsis/blob/main/src/kairopsis/docs/human-guide.md)
|
|
41
|
+
— everyday investigation, Ideas and exports.
|
|
42
|
+
- [Agent setup guide](https://github.com/stabilefrisur/kairopsis/blob/main/src/kairopsis/docs/agent-setup.md)
|
|
43
|
+
— installation, data connections, verification and handoff.
|
|
44
|
+
|
|
45
|
+
Both guides are included in the installed Python package and the source archive.
|
|
46
|
+
Requires Python 3.12 or later. Frontend assets are bundled; no Node.js setup is
|
|
47
|
+
needed.
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Kairopsis
|
|
2
|
+
|
|
3
|
+
A local workspace for relative-value research.
|
|
4
|
+
|
|
5
|
+
Explore market series, compare exposures, and develop investment Ideas with
|
|
6
|
+
charts and notes you can revisit. Kairopsis brings investigation and saved
|
|
7
|
+
evidence together in a browser-based dashboard.
|
|
8
|
+
|
|
9
|
+
- **Investigate:** levels, differences, ratios and regression residuals, with
|
|
10
|
+
historical context and optional risk adjustment.
|
|
11
|
+
- **Retain evidence:** save charts, observations and notes alongside each Idea.
|
|
12
|
+
- **Revisit and share:** compare saved evidence with the latest data and export
|
|
13
|
+
charts or spreadsheet-ready values.
|
|
14
|
+
|
|
15
|
+
A built-in demo lets you explore without market-data credentials. Your research
|
|
16
|
+
stays in a local workspace. Live data access uses Metapyle.
|
|
17
|
+
|
|
18
|
+
## Guides
|
|
19
|
+
|
|
20
|
+
- [Human guide](https://github.com/stabilefrisur/kairopsis/blob/main/src/kairopsis/docs/human-guide.md)
|
|
21
|
+
— everyday investigation, Ideas and exports.
|
|
22
|
+
- [Agent setup guide](https://github.com/stabilefrisur/kairopsis/blob/main/src/kairopsis/docs/agent-setup.md)
|
|
23
|
+
— installation, data connections, verification and handoff.
|
|
24
|
+
|
|
25
|
+
Both guides are included in the installed Python package and the source archive.
|
|
26
|
+
Requires Python 3.12 or later. Frontend assets are bundled; no Node.js setup is
|
|
27
|
+
needed.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Distribute a complete application as a Python wheel
|
|
2
|
+
|
|
3
|
+
Installations may use restricted package indexes and lack Node.js or frontend
|
|
4
|
+
build tools. Ship the application and prepared browser assets together in a
|
|
5
|
+
Python wheel, with the human and agent guides available as package resources.
|
|
6
|
+
|
|
7
|
+
Configuration, credentials and user research belong outside the installed
|
|
8
|
+
package. Runtime dependencies are supplied by the approved package index or a
|
|
9
|
+
prepared wheelhouse. The source archive includes the material needed to build
|
|
10
|
+
and verify a release without cloning its GitHub repository.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Support one local user before shared network deployment
|
|
2
|
+
|
|
3
|
+
The initial deployment runs under one user's account and serves localhost.
|
|
4
|
+
This keeps research and provider access tied to that user's environment.
|
|
5
|
+
|
|
6
|
+
Network binding remains configurable. Shared deployment requires explicit
|
|
7
|
+
decisions about authentication, credential use, reachability and availability,
|
|
8
|
+
because those requirements change the deployment model.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# Use Metapyle as the sole data-access API
|
|
2
|
+
|
|
3
|
+
Kairopsis accesses market data through Metapyle. Keeping provider integrations
|
|
4
|
+
behind that boundary lets the dashboard focus on investigation and retained
|
|
5
|
+
evidence rather than provider-specific connection logic.
|
|
6
|
+
|
|
7
|
+
An installation may select a compatible Metapyle distribution through its
|
|
8
|
+
approved package route. Provider configuration, authentication and private
|
|
9
|
+
implementation changes remain outside the public Kairopsis package. Adapter
|
|
10
|
+
capabilities and observation semantics must be verified in the target environment.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Preserve idea evidence in portable folders
|
|
2
|
+
|
|
3
|
+
Each Idea has an application-managed folder containing readable notes, chart
|
|
4
|
+
images, underlying observations and saved analytical settings. Preserve dated
|
|
5
|
+
Snapshots alongside refreshing charts so an investment argument can be reviewed
|
|
6
|
+
independently of later data or analytical changes.
|
|
7
|
+
|
|
8
|
+
This uses more storage than retaining live chart definitions alone, but keeps
|
|
9
|
+
evidence that may be impossible to reconstruct. Versioned Ideas use atomic
|
|
10
|
+
commit pointers; Snapshots retain JSON, PNG and CSV records. Formats, backup
|
|
11
|
+
and recovery are documented in the [runtime guide](../runtime.md).
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Domain docs
|
|
2
|
+
|
|
3
|
+
## Layout and reading rules
|
|
4
|
+
|
|
5
|
+
This repo uses a single-context layout:
|
|
6
|
+
|
|
7
|
+
- `CONTEXT.md` at the repo root holds domain terminology.
|
|
8
|
+
- `docs/adr/` holds architectural decision records.
|
|
9
|
+
|
|
10
|
+
Before exploring the codebase, read `CONTEXT.md` and the ADRs
|
|
11
|
+
relevant to the area being explored.
|
|
12
|
+
|
|
13
|
+
If these files do not exist, proceed silently. The domain-modeling
|
|
14
|
+
skill creates them when terms or decisions are resolved.
|
|
15
|
+
|
|
16
|
+
## Vocabulary
|
|
17
|
+
|
|
18
|
+
Use the terms defined in `CONTEXT.md` when naming domain concepts
|
|
19
|
+
in issues, proposals, hypotheses, and tests.
|
|
20
|
+
|
|
21
|
+
If a needed concept is absent, reconsider whether it belongs in
|
|
22
|
+
the domain or note the gap for domain-modeling.
|
|
23
|
+
|
|
24
|
+
## Decision conflicts
|
|
25
|
+
|
|
26
|
+
If a proposal contradicts an existing ADR, name that ADR and
|
|
27
|
+
explain why the decision should be reconsidered.
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Issue tracker: Local Markdown
|
|
2
|
+
|
|
3
|
+
Issues and specs live as Markdown files in `.scratch/`.
|
|
4
|
+
|
|
5
|
+
## Conventions
|
|
6
|
+
|
|
7
|
+
- One feature per directory: `.scratch/<feature-slug>/`.
|
|
8
|
+
- Specs live at `.scratch/<feature-slug>/spec.md`.
|
|
9
|
+
- Each implementation ticket has its own file:
|
|
10
|
+
`.scratch/<feature-slug>/issues/<NN>-<slug>.md`, numbered from `01`.
|
|
11
|
+
- Record triage state as a `Status:` line near the top of each issue.
|
|
12
|
+
Use the role strings in `triage-labels.md`.
|
|
13
|
+
- Append comments and conversation history under `## Comments`.
|
|
14
|
+
|
|
15
|
+
## Publishing and fetching
|
|
16
|
+
|
|
17
|
+
When a skill says "publish to the issue tracker", create the
|
|
18
|
+
appropriate file under `.scratch/<feature-slug>/`, creating
|
|
19
|
+
directories as needed.
|
|
20
|
+
|
|
21
|
+
When a skill says "fetch the relevant ticket", read the referenced
|
|
22
|
+
file. Resolve issue numbers within the relevant feature directory.
|
|
23
|
+
|
|
24
|
+
## Wayfinding operations
|
|
25
|
+
|
|
26
|
+
- Map: `.scratch/<effort>/map.md`, with Notes, Decisions-so-far,
|
|
27
|
+
and Fog sections.
|
|
28
|
+
- Child ticket: `.scratch/<effort>/issues/NN-<slug>.md`, numbered
|
|
29
|
+
from `01`, with the question in the body.
|
|
30
|
+
- Type: record `research`, `prototype`, `grilling`, or `task`
|
|
31
|
+
in a `Type:` line.
|
|
32
|
+
- Status: use `open`, `claimed`, or `resolved` for wayfinding tickets.
|
|
33
|
+
- Blocking: record dependencies as `Blocked by: NN, NN`.
|
|
34
|
+
A ticket is unblocked when all listed tickets are resolved.
|
|
35
|
+
- Frontier: select the lowest-numbered open, unblocked,
|
|
36
|
+
unclaimed ticket.
|
|
37
|
+
- Claim: save `Status: claimed` before starting work.
|
|
38
|
+
- Resolve: append the answer under `## Answer`, set
|
|
39
|
+
`Status: resolved`, and add a gist and link to the map's
|
|
40
|
+
Decisions-so-far section.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Triage labels
|
|
2
|
+
|
|
3
|
+
Use these strings in issue files' `Status:` lines when triaging.
|
|
4
|
+
|
|
5
|
+
| Role | Status string | Meaning |
|
|
6
|
+
| --- | --- | --- |
|
|
7
|
+
| needs-triage | needs-triage | Maintainer evaluation needed |
|
|
8
|
+
| needs-info | needs-info | Waiting for more information |
|
|
9
|
+
| ready-for-agent | ready-for-agent | Fully specified; ready for an autonomous agent |
|
|
10
|
+
| ready-for-human | ready-for-human | Requires human implementation |
|
|
11
|
+
| wontfix | wontfix | Will not be actioned |
|
|
12
|
+
|
|
13
|
+
When a skill mentions a triage role, use its mapped status string.
|
|
14
|
+
Wayfinding ticket lifecycle states are defined in `issue-tracker.md`.
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Risk adjustment
|
|
2
|
+
|
|
3
|
+
Investigation uses the Risk adjustment side panel. Changes there are exploratory; **Edit defaults in Library → Use exploratory settings → Save defaults** explicitly adopts them for that Analysis. Opening and monitoring use saved defaults. Idea Snapshots preserve the resolved references, settings, raw observations, transformed inputs and historical scales. Latest uses the captured definition even after catalogue edits/deletion.
|
|
4
|
+
|
|
5
|
+
## Controls and evidence
|
|
6
|
+
|
|
7
|
+
Reference series can be each input itself, a common named series or an external catalogue series. Customize per series exposes independent references/methods/calibration. Each estimator has a lookback; volatility adds equal/exponential weights and half-life, while VaR/CVaR add confidence and downside direction. Frequency belongs to the Analysis and is daily, weekly or monthly. Self-beta is allowed, so both inputs can be adjusted to the first input.
|
|
8
|
+
|
|
9
|
+
Legend click toggles a trace; double-click isolates it. Axes stay fixed and hidden labels remain dimmed. Visibility changes presentation only. Save to Idea and image exports preserve the selected visibility and scales; older Snapshots remain readable. Shared source metadata and adjustment summaries appear once in the footnote, with full calibration and estimates under Source and chart details.
|
|
10
|
+
|
|
11
|
+
## Calculation contract
|
|
12
|
+
|
|
13
|
+
Adjustment applies to each measured input before the Standalone or Pair calculation. The Measured / adjusted series chart compares the individual inputs; Analysis shows the selected difference, ratio or regression residual. Underlying series shows original levels. Display range never changes estimation.
|
|
14
|
+
|
|
15
|
+
Frequency uses the existing calendar convention: daily = previous weekday; weekly = seven calendar days; monthly = previous calendar month with day clamped. Weekly/monthly baselines are backward-only within three calendar days. Both endpoints require actual observations on their row dates; no fill. Weekly/monthly moves are overlapping observations sampled at daily endpoints. No square-root-of-time conversion or annualization is applied.
|
|
16
|
+
|
|
17
|
+
Change is `current − baseline`, in supplied units. Percentage change is `100 × (current / baseline − 1)` and requires a positive baseline. This is a percentage change in the supplied measure, not a total investment return inferred from spread levels. To examine supplied cumulative return series, choose their configured Data Series.
|
|
18
|
+
|
|
19
|
+
For each date, the risk sample ends at the measured interval's start and begins the selected number of calendar years earlier. The current measured interval is excluded. At least 60 valid prior moves are required by default. Estimation history older than seven calendar days at that cutoff is unavailable. Beta uses paired moves with identical start/end dates. Source freshness qualifications still apply to findings.
|
|
20
|
+
|
|
21
|
+
| Method | Divisor / convention |
|
|
22
|
+
| --- | --- |
|
|
23
|
+
| None | 1; preserves measured changes. Existing Analyses retain unadjusted levels by default. |
|
|
24
|
+
| Volatility | Demeaned sample standard deviation. Equal weights use `N−1`. Exponential weights use `w = 2^(−age/half-life)`, with age/half-life in weekday sessions; normalized weighted variance uses denominator `Σw − Σw²/Σw`. |
|
|
25
|
+
| Beta to reference | Intercept OLS slope `Σ(x−x̄)(y−ȳ) / Σ(x−x̄)²`; y is the target and x the reference. Self-beta equals 1 when reference moves vary. Signed negative beta is retained; absolute beta below `1e−12` is unavailable. |
|
|
26
|
+
| Value at Risk | Historical loss quantile: sorted loss at `ceil(confidence × N)`. Confidence is converted from percent. Increasing or decreasing values explicitly defines downside. |
|
|
27
|
+
| Expected Shortfall (CVaR) | Mean of the worst `(1−confidence) × N` losses, including proportional weight for a fractional boundary observation. Uses the same downside direction as VaR. |
|
|
28
|
+
|
|
29
|
+
The input is divided by its estimated scale without subtracting a drift or intercept. Volatility/VaR/ES yield dimensionless **risk units** and require matching target/reference units, or percentage changes. Beta yields the reference's units. Pair differences require identical resulting units; ratios preserve the units of the quotient. Zero variance, missing estimates, near-zero beta and nonpositive downside scales produce unavailable values. Per-series customization can therefore produce incompatible differences; the UI retains the last accepted evaluation and explains the incompatibility.
|
|
30
|
+
|
|
31
|
+
VaR/ES describe downside moves of the selected Data Series, not portfolio P&L or capital requirements. High confidence with few observations has little tail evidence; disclosed sample counts and periods are essential. These historical estimates are comparisons, not calibrated trading or investment recommendations.
|
|
32
|
+
|
|
33
|
+
## Defaults, thresholds and continuity
|
|
34
|
+
|
|
35
|
+
None preserves existing level behavior and older stored evidence remains readable. Selecting an adjustment from a level Analysis switches Measure to Change. Changing risk configuration or Measure clears exploratory move/materiality thresholds, preventing old measurement-unit rules from being reused silently. Library exposes explicit thresholds in the resulting Analysis units; production threshold calibration remains separate.
|
|
36
|
+
|
|
37
|
+
References are resolved and fetched through Metapyle alongside the inputs. Reference edits advance dependent Analysis revisions; deletion is prevented while an active Analysis uses that reference. Captured definitions retain the binding needed for Latest evaluation independently of active catalogue entries. Snapshots contain raw reference data in JSON; CSV/clipboard exports additionally include measured inputs, scales and period starts.
|
|
38
|
+
|
|
39
|
+
## Sources and scope
|
|
40
|
+
|
|
41
|
+
Definitions follow [BIS market-risk terminology](https://www.bis.org/committees/bcbs/basel-framework/standard/mar?allChapters=true&q=PPP0QQQ&sort=PPP1QQQ&year=PPP2QQQ) for VaR/ES, [NIST least squares](https://www.itl.nist.gov/div898/handbook/pmd/section4/pmd431.htm) for intercept regression, and [NIST exponential smoothing](https://www.itl.nist.gov/div898/handbook/pmc/section4/pmc43.htm) for decaying weights. The finite-sample correction, empirical quantile, fractional-tail and calendar conventions above are explicit implementation choices; no regulatory methodology is claimed.
|
|
42
|
+
|
|
43
|
+
Mock tests establish numerical and persistence behavior. Provider calendars, actual source semantics, estimator suitability and risk-adjusted monitoring thresholds require validation in the target environment.
|
|
44
|
+
|
|
45
|
+
The [verification guide](verification.md) describes source and installed-package checks. A source test result does not establish acceptance for a different operating system or data provider.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Run and preserve research
|
|
2
|
+
|
|
3
|
+
Python 3.12+, FastAPI/Uvicorn, Jinja2 and plain JavaScript. All browser assets are packaged locally. Install the wheel and dependencies before launch; startup never resolves dependencies. Three destinations: Analyses, Ideas, Library.
|
|
4
|
+
|
|
5
|
+
```powershell
|
|
6
|
+
kairopsis --mode mock --host 127.0.0.1 --port 8765 --workspace C:\Users\Me\Kairopsis\rebuild-mock
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Use the environment's absolute `Scripts\kairopsis.exe` in Windows Task Scheduler. Working directory does not matter. Paths (`--workspace`, `--config-dir`, `--cache-dir`, `--log-dir`) must be absolute, writable and outside the installed package. `--timezone Europe/London` sets daily refresh boundaries. CLI overrides `KAIROPSIS_<KEY>` environment variables, optional `--config C:\absolute\kairopsis.toml` (`[kairopsis]` keys with underscores), then platform defaults.
|
|
10
|
+
|
|
11
|
+
Mock fixtures are deterministic, explicitly fabricated native-market observations through **30 September 2026**. No credentials/provider connection. New Library bindings require a matching fixture; unavailable bindings produce explicit failures. Monitoring is independent of saving to an Idea. First daily opening starts refresh in the background; manual Refresh completes a dated attempt. Failed analyses retain their prior result and lose fresh finding eligibility.
|
|
12
|
+
|
|
13
|
+
## Evidence and recovery
|
|
14
|
+
|
|
15
|
+
The rebuild uses workspace schema 2. Older/unmarked nonempty workspaces are refused without modification. Choose a new empty directory; no migration or deletion is performed. Retain older user directories independently.
|
|
16
|
+
|
|
17
|
+
`workspace/ideas/<id>/current.json` selects a committed version under `versions/<version>/idea.json` and `notes.md`. `snapshots/<id>/` contains `snapshot.json`, `image.png` and `data.csv`. Snapshot JSON embeds resolved inputs/risk references, analytical settings, raw/aligned observations, measured inputs/scales/interval starts and retrieval/capture times. Display settings include hidden trace indices and axis ranges; the PNG has a verified content hash. Catalogue and dated evaluation/refresh records live outside the package. No database index is the only copy of evidence.
|
|
18
|
+
|
|
19
|
+
Files for a version are written before its atomic commit pointer. Interrupted saves leave the previous version readable; unpublished directories are ignored. Snapshot metadata is committed last. Disk/read errors stop capture/export with an actionable message. Removing a chart/note preserves prior versions and Snapshots internally. No History destination is required.
|
|
20
|
+
|
|
21
|
+
Saved charts render their frozen observations and settings with the current presentation; Saved/Latest share chart geometry. Original PNGs remain unchanged and can be downloaded under Source and chart details. A chart note sits directly below its plot, with Edit/Delete beside it and source disclosure last.
|
|
22
|
+
|
|
23
|
+
Legend click shows/hides a series; double-click isolates it. Hidden labels stay dimmed and axes remain fixed while toggling. Image exports and Save to Idea capture `hidden_traces` and `axis_ranges` in DisplaySettings. Older records default to all traces visible and automatic initial scales. Latest keeps the captured selection and recalculates scales from all current traces; changing chart view resets selection. Underlying values and analytical metrics remain unchanged by visibility.
|
|
24
|
+
|
|
25
|
+
Idea chart actions are Copy data, Copy chart, Download chart, Remove chart. Image actions use the selected view. Copy data uses its full displayed period and supplies spreadsheet-ready TSV with calculated/input values, units, ISO chart/source dates, measured/adjusted inputs, risk scales and interval starts, full numeric precision and blank missing cells. Legend visibility does not remove input columns. Clipboard denial downloads the corresponding PNG or TSV. Copy/export first captures another Snapshot; a capture failure stops completion and preserves the clipboard. Original saved evidence is never overwritten.
|
|
26
|
+
|
|
27
|
+
Footnotes deduplicate shared source, currency/reference curve and observation dates, with a compact method/reference/Frequency summary for adjusted views. Demo status and applicable fit period remain explicit. Full per-series bindings, calibration, retrieval and quality details stay folded and in portable records. Date axes have no title; numeric scatter axes retain series/unit titles. Idea detail omits the saved-chart count. Owned UI asset URLs include content hashes, so refresh loads changed scripts/styles.
|
|
28
|
+
|
|
29
|
+
Stop the application before copying the entire workspace for backup. Restore to a separate empty directory and point `--workspace` there. An Idea folder can also be copied under another compatible workspace's `ideas/`; its current pointer and embedded evidence suffice to reopen it. Never copy only images or an index. Preserve corrupt content for recovery; restore a known-good backup rather than resetting a directory.
|
|
30
|
+
|
|
31
|
+
## Live data and verification
|
|
32
|
+
|
|
33
|
+
Start `--mode live` in a separate workspace. Library **Add data series** creates a Metapyle catalogue entry; Edit/Delete update it. No separate translation configuration is needed for new entries.
|
|
34
|
+
|
|
35
|
+
The form uses actual provider identifiers:
|
|
36
|
+
|
|
37
|
+
| Source | Required query fields |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| Bloomberg | Symbol/ticker and field |
|
|
40
|
+
| Macrobond | Series symbol; no field or path |
|
|
41
|
+
| Local file | Case-sensitive column name and absolute CSV/Parquet path; no field |
|
|
42
|
+
| Other registered source | Registered adapter name and its supported symbol/field/path/parameters |
|
|
43
|
+
|
|
44
|
+
Name is the display label. Catalogue name (`my_name`) defaults to the name with underscores and can be edited under additional details. Units are required. Currency describes the data; Description is optional. Reference curve, comparison currency and adjustment/rebasing have been removed from the form. New series do not generate a comparison-basis record; existing metadata remains readable in earlier definitions and saved evidence. Provider credentials remain in the provider's runtime configuration, outside catalogue query parameters.
|
|
45
|
+
|
|
46
|
+
`workspace/metapyle.yaml` is a real YAML catalogue readable by Metapyle. Library owns this file: edit entries through Library. `catalogue.json` commits series metadata and analysis dependencies together; YAML is a validated projection rebuilt at startup. A failed metadata commit restores the preceding YAML. Both files belong in workspace backups. Concurrent external edits/import of independent catalogues are not supported in this version.
|
|
47
|
+
|
|
48
|
+
Metapyle validates source-specific attributes and registered sources before publication. Structural validation does not prove that a symbol exists or that it represents the intended asset. Library save does not fetch observations. Source failures and missing expected columns remain explicit.
|
|
49
|
+
|
|
50
|
+
Retrieval uses `Client(catalog=..., cache_enabled=False)` → `get([my_name], ..., use_cache=False)` → `close()`. A new client loads each request's catalogue. Active definitions use the managed YAML; frozen definitions use a temporary catalogue containing their captured entries when current entries differ or have been removed. No frequency alignment is requested from Metapyle; analytical Frequency remains in Kairopsis.
|
|
51
|
+
|
|
52
|
+
Public adapter responses remain freshness **unverified** and native observation dates unknown. They support inspectable charts and saved evidence but cannot establish eligible findings. Observation cache bypass remains deliberate; catalogue files are definitions, not an observation cache. Installed adapter capabilities, upstream freshness, calendars and dependency routing require verification in the target environment.
|
|
53
|
+
|
|
54
|
+
Existing demo fixtures and old snapshots without `catalog_name` keep their previous binding contract. Old live bindings alone may use private `config-dir/metapyle.json` mappings and `get_raw()` for compatibility, including explicitly configured observation-date columns. Edit an old live series, select its real provider and supply its actual symbol/field/path to move future evaluations to the catalogue API. Prior snapshots keep their captured definitions. No automatic translation or guessed migration is performed.
|
|
55
|
+
|
|
56
|
+
Public Metapyle 0.1.6 has no add/update/remove API or CLI. Kairopsis uses `Catalog` export/load and public `Client` validation behind one module. A generic upstream request tracks those additions: [Metapyle issue #3](https://github.com/stabilefrisur/metapyle/issues/3).
|
|
57
|
+
|
|
58
|
+
## Analytical conventions
|
|
59
|
+
|
|
60
|
+
| Item | Applied rule |
|
|
61
|
+
| --- | --- |
|
|
62
|
+
| Standing | Current-excluded eligible history; `100 × (below + 0.5 × equal) / N`; default reference 3 calendar years; at least 60 prior points. Shorter available history is qualified by sample count. |
|
|
63
|
+
| Alignment | Exact supplied row dates, no fill/interpolation. Findings require finite inputs and known native dates equal to the row; weekdays only. Union rows remain inspectable with missing arithmetic. Provider holiday calendars are not verified. |
|
|
64
|
+
| Day move | Exact previous weekday session; never skip a missing baseline. |
|
|
65
|
+
| Week/month move | Seven calendar days / previous calendar month (day clamped); backward-only baseline within three calendar days. Missing baseline yields unavailable, never zero. |
|
|
66
|
+
| Pair | Ordered first minus second, first divided by second (zero denominator unavailable), or first dependent on second explanatory. Difference requires same units; different bases remain explicitly labelled. |
|
|
67
|
+
| OLS | Intercept fit over selected full trailing calendar window excluding current. At least 20 eligible pairs; seven-day endpoint tolerance; constant x unavailable. Residual history uses current fit retrospectively. Fit and display/reference windows are independent. |
|
|
68
|
+
| Sensitivity | Compare 1y/5y fits where full history permits; indicate a residual direction reversal. Unavailable checks are explicit; no invented stability score. |
|
|
69
|
+
| Finding | Configured symmetric level tails and optional native-unit move thresholds. `demo-native-v1` explicitly illustrative. Compatible new native observations establish threshold entry or material movement; same evidence stays quiet. Corrections/definition/method changes suppress market novelty. Regression material movement holds the earlier fit fixed. |
|
|
70
|
+
| Ordering | New, materially changed, first-observed condition; then case-folded name and stable ID. One row per analysis, no composite score/quota. |
|
|
71
|
+
|
|
72
|
+
Risk adjustment is available in the Investigation side panel and as saved Analysis defaults in Library. Supported methods: volatility, beta, historical VaR and Expected Shortfall (CVaR), with common or per-input references/settings. [Calculation conventions](risk-adjustment.md) specify Frequency, prior-only estimation, half-life, downside, units and unavailable cases. Snapshots preserve raw/reference data and adjustment choices; Latest uses the captured definition. Estimator suitability and risk-adjusted monitoring thresholds require target-environment validation.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
# Verify a distribution
|
|
2
|
+
|
|
3
|
+
Verify the built artifacts as well as the source checkout. Source tests establish
|
|
4
|
+
application behavior; installed-package checks establish that the distribution
|
|
5
|
+
contains the code, browser assets and guides needed outside the checkout.
|
|
6
|
+
|
|
7
|
+
## Source and packaging checks
|
|
8
|
+
|
|
9
|
+
```sh
|
|
10
|
+
uv sync --locked
|
|
11
|
+
uv run pytest -q
|
|
12
|
+
uv run mypy src/kairopsis
|
|
13
|
+
uv build
|
|
14
|
+
uv run python scripts/acceptance/inspect_wheel.py dist/kairopsis-0.1.0-py3-none-any.whl --require-assets --source-directory . --output /absolute/output/wheel-inventory.json
|
|
15
|
+
uvx --from twine twine check --strict dist/*
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
The inventory requires both installed guides, checks source completeness and
|
|
19
|
+
vendor checksums, and rejects accidental private runtime material. Source archives
|
|
20
|
+
include docs, tests, scripts, the lockfile and domain context. Keep scratch records
|
|
21
|
+
and credentials outside published artifacts.
|
|
22
|
+
|
|
23
|
+
## Installed application
|
|
24
|
+
|
|
25
|
+
Install the wheel into a separate environment with approved dependencies. Launch
|
|
26
|
+
from outside the checkout using fresh writable directories. Verify all three
|
|
27
|
+
navigation destinations, local assets, an Analysis, saved Idea evidence, notes,
|
|
28
|
+
exports and restart persistence. Locate the two installed guides through
|
|
29
|
+
`importlib.resources` as described in the [agent setup guide](../src/kairopsis/docs/agent-setup.md).
|
|
30
|
+
|
|
31
|
+
For an automated journey against an isolated running demo instance:
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
uv run python scripts/browser_acceptance.py --url http://127.0.0.1:8765 --output /absolute/output/browser
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The script creates verification records. Supply a separate workspace rather than
|
|
38
|
+
an existing research workspace. Prepare Playwright Chromium before network-limited
|
|
39
|
+
checks. `scripts/acceptance/run_windows.py` also provides an installed Windows
|
|
40
|
+
harness; its output directory must not exist.
|
|
41
|
+
|
|
42
|
+
## Recorded scope
|
|
43
|
+
|
|
44
|
+
The current implementation passes 63 source tests. Typechecking, packaged source
|
|
45
|
+
and browser-asset inventory, installed guide discovery and strict Twine checks
|
|
46
|
+
have passed. Tests also run from an extracted source archive without a checkout.
|
|
47
|
+
|
|
48
|
+
An installed Linux demo has loaded all navigation pages and local assets and
|
|
49
|
+
produced a mock Analysis preview from a separate environment. Full installed
|
|
50
|
+
Windows and live-provider acceptance must be verified for the target release.
|
|
51
|
+
Provider credentials, data semantics, calendars, freshness and monitoring
|
|
52
|
+
threshold suitability are separate from package completeness.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "kairopsis"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Relative-value idea generation dashboard powered by metapyle"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
dependencies = [
|
|
8
|
+
"fastapi==0.135.2",
|
|
9
|
+
"jinja2==3.1.6",
|
|
10
|
+
"metapyle>=0.1.6",
|
|
11
|
+
"pandas==3.0.6",
|
|
12
|
+
"platformdirs==4.5.1",
|
|
13
|
+
"pydantic==2.13.5",
|
|
14
|
+
"tzdata==2026.4",
|
|
15
|
+
"uvicorn==0.42.0",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[[project.authors]]
|
|
19
|
+
name = "Stabile Frisur"
|
|
20
|
+
email = "26568863+stabilefrisur@users.noreply.github.com"
|
|
21
|
+
|
|
22
|
+
[project.scripts]
|
|
23
|
+
kairopsis = "kairopsis:main"
|
|
24
|
+
|
|
25
|
+
[project.urls]
|
|
26
|
+
Repository = "https://github.com/stabilefrisur/kairopsis"
|
|
27
|
+
Documentation = "https://github.com/stabilefrisur/kairopsis/blob/main/src/kairopsis/docs/human-guide.md"
|
|
28
|
+
Issues = "https://github.com/stabilefrisur/kairopsis/issues"
|
|
29
|
+
|
|
30
|
+
[build-system]
|
|
31
|
+
requires = ["uv_build>=0.12.19,<0.13.0"]
|
|
32
|
+
build-backend = "uv_build"
|
|
33
|
+
|
|
34
|
+
[dependency-groups]
|
|
35
|
+
dev = [
|
|
36
|
+
"httpx==0.28.1",
|
|
37
|
+
"mypy==1.18.2",
|
|
38
|
+
"playwright==1.55.0",
|
|
39
|
+
"pytest==8.4.2",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[tool.uv.build-backend]
|
|
43
|
+
source-include = [
|
|
44
|
+
"docs/**",
|
|
45
|
+
"tests/**",
|
|
46
|
+
"scripts/**",
|
|
47
|
+
"uv.lock",
|
|
48
|
+
"CONTEXT.md",
|
|
49
|
+
"AGENTS.md",
|
|
50
|
+
".python-version",
|
|
51
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "kairopsis"
|
|
3
|
+
version = "0.1.0"
|
|
4
|
+
description = "Relative-value idea generation dashboard powered by metapyle"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "Stabile Frisur", email = "26568863+stabilefrisur@users.noreply.github.com" }
|
|
8
|
+
]
|
|
9
|
+
requires-python = ">=3.12"
|
|
10
|
+
dependencies = [
|
|
11
|
+
"fastapi==0.135.2",
|
|
12
|
+
"jinja2==3.1.6",
|
|
13
|
+
"metapyle>=0.1.6",
|
|
14
|
+
"pandas==3.0.6",
|
|
15
|
+
"platformdirs==4.5.1",
|
|
16
|
+
"pydantic==2.13.5",
|
|
17
|
+
"tzdata==2026.4",
|
|
18
|
+
"uvicorn==0.42.0",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[project.scripts]
|
|
22
|
+
kairopsis = "kairopsis:main"
|
|
23
|
+
|
|
24
|
+
[project.urls]
|
|
25
|
+
Repository = "https://github.com/stabilefrisur/kairopsis"
|
|
26
|
+
Documentation = "https://github.com/stabilefrisur/kairopsis/blob/main/src/kairopsis/docs/human-guide.md"
|
|
27
|
+
Issues = "https://github.com/stabilefrisur/kairopsis/issues"
|
|
28
|
+
|
|
29
|
+
[build-system]
|
|
30
|
+
requires = ["uv_build>=0.12.19,<0.13.0"]
|
|
31
|
+
build-backend = "uv_build"
|
|
32
|
+
|
|
33
|
+
[dependency-groups]
|
|
34
|
+
dev = [
|
|
35
|
+
"httpx==0.28.1",
|
|
36
|
+
"mypy==1.18.2",
|
|
37
|
+
"playwright==1.55.0",
|
|
38
|
+
"pytest==8.4.2",
|
|
39
|
+
]
|
|
40
|
+
|
|
41
|
+
[tool.uv.build-backend]
|
|
42
|
+
source-include = ["docs/**", "tests/**", "scripts/**", "uv.lock", "CONTEXT.md", "AGENTS.md", ".python-version"]
|