Skip to content

Commit 6eb9e44

Browse files
committed
Ship TradingCodex 0.1.0a5
1 parent 3a7f2e9 commit 6eb9e44

10 files changed

Lines changed: 46 additions & 12 deletions

File tree

docs/deployment.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ python3.14 -m venv /tmp/tcx-testpypi
133133
/tmp/tcx-testpypi/bin/pip install \
134134
--index-url https://test.pypi.org/simple/ \
135135
--extra-index-url https://pypi.org/simple/ \
136-
tradingcodex==0.1.0a4
136+
tradingcodex==0.1.0a5
137137
rm -rf /tmp/tcx-testpypi-smoke
138138
mkdir -p /tmp/tcx-testpypi-smoke
139139
cd /tmp/tcx-testpypi-smoke
@@ -162,7 +162,7 @@ After the PyPI workflow completes:
162162

163163
```bash
164164
python3.14 -m venv /tmp/tcx-pypi
165-
/tmp/tcx-pypi/bin/pip install tradingcodex==0.1.0a4
165+
/tmp/tcx-pypi/bin/pip install tradingcodex==0.1.0a5
166166
rm -rf /tmp/tcx-pypi-smoke
167167
mkdir -p /tmp/tcx-pypi-smoke
168168
cd /tmp/tcx-pypi-smoke
@@ -183,7 +183,7 @@ cd /tmp/tcx-install-sh-smoke
183183

184184
Use PEP 440 versions:
185185

186-
- `0.1.0a1`, `0.1.0a2`, `0.1.0a3`, `0.1.0a4` for alpha releases
186+
- `0.1.0a1`, `0.1.0a2`, `0.1.0a3`, `0.1.0a4`, `0.1.0a5` for alpha releases
187187
- `0.1.0b1` for beta releases
188188
- `0.1.0rc1` for release candidates
189189
- `0.1.0` only after install, docs, DB migration, and generated workspace

docs/tradingcodex-prd.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ Multiple Codex projects / subagents / local CLI
5858
-> product web review dashboard, Django-hosted MCP endpoint, or stdio bridge
5959
-> Django service layer
6060
-> central Django DB-backed policy, research, orders, portfolio, audit, harness, integrations
61-
-> paper/stub/live adapter boundary
61+
-> paper/stub adapter boundary; future live adapters only after separate installation and policy approval
6262
```
6363

6464
The source tree is organized around the Python product:
@@ -229,6 +229,12 @@ Django Ninja provides local/staff typed control APIs:
229229
- `POST /api/research/search`
230230
- `POST /api/research/source-snapshots`
231231

232+
The canonical approval and execution routes are `/api/approvals` and
233+
`/api/executions/submit-approved`. The service may also keep compatibility
234+
aliases under `/api/orders/approvals` and `/api/orders/executions/submit-approved`;
235+
these aliases call the same service-layer functions and do not widen execution
236+
permissions.
237+
232238
OpenAPI docs are staff-protected. REST is for operations, validation, inspection, and local control; it must not bypass MCP/service-layer execution checks.
233239

234240
## MCP Boundary

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "tradingcodex"
7-
version = "0.1.0a4"
7+
version = "0.1.0a5"
88
description = "Codex-native trading harness with a Django service plane and MCP execution boundary."
99
readme = "README.md"
1010
requires-python = ">=3.14,<3.15"

tests/test_python_migration.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
validate_order_intent,
2222
)
2323
from tradingcodex_service.mcp_runtime import static_mcp_tools
24+
from tradingcodex_service.version import TRADINGCODEX_VERSION
2425

2526

2627
ROOT = Path(__file__).resolve().parents[1]
@@ -72,6 +73,7 @@ def test_template_copy_skips_python_bytecode_cache(tmp_path: Path) -> None:
7273
def test_python_generator_creates_workspace_contract(tmp_path: Path) -> None:
7374
workspace = make_workspace(tmp_path)
7475
assert (workspace / "pyproject.toml").exists()
76+
assert f'version = "{TRADINGCODEX_VERSION}"' in (workspace / "pyproject.toml").read_text(encoding="utf-8")
7577
assert not (workspace / "package.json").exists()
7678
assert (workspace / "tcx").exists()
7779
assert not (workspace / "tradingcodex").exists()
@@ -101,13 +103,32 @@ def test_python_generator_creates_workspace_contract(tmp_path: Path) -> None:
101103
assert "head-manager MCP execution submit excluded" in doctor
102104
assert "execution-operator MCP execution allowlist configured" in doctor
103105
assert "risk-manager MCP approval allowlist configured" in doctor
106+
hooks = json.loads((workspace / ".codex" / "hooks.json").read_text(encoding="utf-8"))["hooks"]
107+
expected_hook_events = {
108+
"SessionStart",
109+
"PreToolUse",
110+
"PermissionRequest",
111+
"PostToolUse",
112+
"UserPromptSubmit",
113+
"SubagentStart",
114+
"SubagentStop",
115+
"Stop",
116+
}
117+
assert set(hooks) == expected_hook_events
118+
assert "matcher" not in hooks["UserPromptSubmit"][0]
119+
assert "matcher" not in hooks["Stop"][0]
120+
assert hooks["PreToolUse"][0]["matcher"] == "Bash|mcp__.*"
121+
assert hooks["SubagentStart"][0]["matcher"]
104122
service_usage = run(["./tcx", "service", "nope"], workspace, expect_ok=False)
105123
assert "Usage: tcx service runserver [addrport] [django runserver args]" in service_usage.stderr
106124
agent_files = sorted((workspace / ".codex" / "agents").glob("*.toml"))
107125
assert len(agent_files) == 9
108126
actual_mcp_tools = {tool["name"] for tool in static_mcp_tools()}
109127
stale_mcp_tool_names = {"evaluate_policy", "get_positions_snapshot", "write_audit_event"}
110128
root_config = tomllib.loads((workspace / ".codex" / "config.toml").read_text(encoding="utf-8"))
129+
assert root_config["default_permissions"] == "tradingcodex"
130+
assert root_config["permissions"]["tradingcodex"]["extends"] == ":workspace"
131+
assert root_config["permissions"]["tradingcodex"]["network"]["enabled"] is False
111132
root_mcp = root_config["mcp_servers"]["tradingcodex"]
112133
assert root_mcp["command"] == "uvx"
113134
assert root_mcp["args"] == ["--python", "3.14", "--from", "tradingcodex", "tcx", "mcp", "stdio"]
@@ -124,9 +145,12 @@ def test_python_generator_creates_workspace_contract(tmp_path: Path) -> None:
124145
assert "cancel_approved_order" not in root_mcp["enabled_tools"]
125146
for agent_file in agent_files:
126147
agent_config = agent_file.read_text(encoding="utf-8")
148+
agent_toml = tomllib.loads(agent_config)
149+
assert agent_toml["name"] == agent_file.stem
150+
assert agent_toml["description"]
151+
assert agent_toml["developer_instructions"]
127152
assert 'model = "gpt-5.5"' in agent_config
128153
assert 'model_reasoning_effort = "high"' in agent_config
129-
agent_toml = tomllib.loads(agent_config)
130154
agent_mcp = agent_toml["mcp_servers"]["tradingcodex"]
131155
assert agent_mcp["command"] == "uvx"
132156
assert agent_mcp["args"] == ["--python", "3.14", "--from", "tradingcodex", "tcx", "mcp", "stdio"]
@@ -189,7 +213,7 @@ def test_init_current_directory_and_overwrite_language(tmp_path: Path) -> None:
189213

190214
assert f"TradingCodex workspace created: {workspace.resolve()}" in result.stdout
191215
assert (workspace / "tcx").exists()
192-
assert json.loads((workspace / ".tradingcodex" / "generated" / "module-lock.json").read_text(encoding="utf-8"))["tradingcodex_version"] == "0.1.0a4"
216+
assert json.loads((workspace / ".tradingcodex" / "generated" / "module-lock.json").read_text(encoding="utf-8"))["tradingcodex_version"] == TRADINGCODEX_VERSION
193217

194218
repeated = run([sys.executable, "-m", "tradingcodex_cli", "init", "."], workspace, expect_ok=False, env_extra=env_extra)
195219
assert "--overwrite" in repeated.stderr

tradingcodex_cli/generator.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
from pathlib import Path
1010
from typing import Any
1111

12+
from tradingcodex_service.version import TRADINGCODEX_VERSION
13+
1214
DEFAULT_MODULE_IDS = [
1315
"codex-base",
1416
"fixed-subagents",
@@ -51,7 +53,7 @@ def bootstrap_workspace(project_dir: Path | str, force: bool = False, dry_run: b
5153
"SOURCE_ROOT": str(repo_root()),
5254
"PYTHON_EXECUTABLE": sys.executable,
5355
"GENERATED_AT": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
54-
"TRADINGCODEX_VERSION": "0.1.0a4",
56+
"TRADINGCODEX_VERSION": TRADINGCODEX_VERSION,
5557
"TRADINGCODEX_MCP_PACKAGE_SPEC": os.environ.get("TRADINGCODEX_MCP_PACKAGE_SPEC", "tradingcodex"),
5658
"SUBAGENT_COUNT": str(len(subagents)),
5759
}

tradingcodex_cli/workspace.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import annotations
22

3-
import argparse
43
import json
54
import os
65
import sys

tradingcodex_service/__init__.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from tradingcodex_service.version import TRADINGCODEX_VERSION
2+
13
__all__ = ["__version__"]
24

3-
__version__ = "0.1.0a4"
5+
__version__ = TRADINGCODEX_VERSION

tradingcodex_service/domain.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
from pathlib import Path
1111
from typing import Any
1212

13+
from tradingcodex_service.version import TRADINGCODEX_VERSION
1314

14-
TRADINGCODEX_VERSION = "0.1.0a4"
1515
DEFAULT_MAX_SINGLE_ORDER_KRW = 100_000_000
1616
DEFAULT_ALLOWED_ADAPTERS = {"stub-execution", "paper-trading"}
1717
DEFAULT_PAPER_CASH_KRW = 100_000_000

tradingcodex_service/version.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TRADINGCODEX_VERSION = "0.1.0a5"

workspace_templates/modules/codex-base/files/pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "{{PROJECT_NAME}}"
3-
version = "0.1.0a4"
3+
version = "{{TRADINGCODEX_VERSION}}"
44
requires-python = ">=3.14,<3.15"
55
dependencies = [
66
"django>=5.2,<5.3",

0 commit comments

Comments
 (0)