tradingcodex 0.3.2__tar.gz → 0.3.4__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.
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/PKG-INFO +2 -2
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/README.md +1 -1
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/mcp/admin.py +2 -0
- tradingcodex-0.3.4/apps/mcp/migrations/0002_mcpexternalpermissionrequest.py +51 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/mcp/models.py +28 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/mcp/services.py +187 -4
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/README.md +1 -1
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/deployment.md +16 -45
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/generated-workspaces.md +15 -4
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/interfaces-and-surfaces.md +11 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/roles-skills-and-workflows.md +5 -2
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/safety-policy-and-execution.md +8 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/pyproject.toml +1 -1
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tests/test_python_migration.py +332 -5
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex.egg-info/PKG-INFO +2 -2
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex.egg-info/SOURCES.txt +4 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/__main__.py +3 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/bootstrap.py +1 -1
- tradingcodex-0.3.4/tradingcodex_cli/commands/build.py +148 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/mcp.py +2 -12
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/profile.py +6 -14
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/service_autostart.py +28 -4
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/startup_status.py +39 -7
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/agents.py +1 -16
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/brokers.py +0 -18
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/components.py +1 -1
- tradingcodex-0.3.4/tradingcodex_service/application/customization.py +337 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/mcp_runtime.py +20 -1
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/static/tradingcodex_web/app.css +92 -66
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/agents.html +15 -12
- tradingcodex-0.3.4/tradingcodex_service/templates/web/build_center.html +196 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/fragments/starter_prompt.html +53 -59
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/mcp_router.html +1 -1
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/research.html +15 -12
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/strategies.html +15 -12
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/urls.py +4 -0
- tradingcodex-0.3.4/tradingcodex_service/version.py +1 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/web.py +109 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.codex/prompts/base_instructions/head-manager.md +12 -3
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/tcx +0 -3
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/tcx-build/SKILL.md +11 -7
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/tcx-build/agents/openai.yaml +2 -2
- tradingcodex-0.3.2/tradingcodex_service/version.py +0 -1
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/CONTRIBUTING.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/LICENSE +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/MANIFEST.in +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/NOTICE +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/TRADEMARKS.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/audit/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/audit/admin.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/audit/apps.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/audit/migrations/0001_initial.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/audit/migrations/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/audit/models.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/harness/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/harness/admin.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/harness/apps.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/harness/migrations/0001_initial.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/harness/migrations/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/harness/models.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/harness/templatetags/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/integrations/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/integrations/admin.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/integrations/apps.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/integrations/migrations/0001_initial.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/integrations/migrations/0002_brokerconnection_brokeraccount_instrumentmap.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/integrations/migrations/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/integrations/models.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/mcp/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/mcp/apps.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/mcp/migrations/0001_initial.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/mcp/migrations/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/admin.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/apps.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/migrations/0001_initial.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/migrations/0002_approvalreceipt_approved_order_type_and_more.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/migrations/0003_migrate_orderintent_to_orderticket.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/migrations/0004_remove_order_intent_compat_fields.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/migrations/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/models.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/orders/services.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/policy/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/policy/admin.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/policy/apps.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/policy/migrations/0001_initial.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/policy/migrations/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/policy/models.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/policy/services.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/portfolio/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/portfolio/admin.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/portfolio/apps.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/portfolio/migrations/0001_initial.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/portfolio/migrations/0002_brokersyncrun_portfolioledgerevent_reconciliationrun.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/portfolio/migrations/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/portfolio/models.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/workflows/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/workflows/admin.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/workflows/apps.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/workflows/migrations/0001_initial.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/workflows/migrations/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/apps/workflows/models.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/assets/tradingcodex-banner.svg +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/artifact-supervisor-loop-prd.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/components.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/core-concepts-and-rules.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/financial-workflow-references.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/guardrails.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/harness.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/improvement-loop.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/licensing-and-commercialization.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/product-direction.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/research-memory-and-artifacts.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/system-architecture.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/user-facing-skills.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/docs/validation-and-test-plan.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/install.sh +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/installation.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/setup.cfg +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tests/test_broker_center_prd.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tests/test_e2e_user_scenarios.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex.egg-info/dependency_links.txt +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex.egg-info/entry_points.txt +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex.egg-info/requires.txt +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex.egg-info/top_level.txt +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/connectors.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/db.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/decision.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/doctor.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/mode.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/orders.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/policy.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/research.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/skills.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/strategies.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/subagents.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/utils.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/workflow.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/commands/workspaces.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/generator.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_cli/mcp_stdio.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/admin.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/api.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/artifact_quality.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/audit.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/common.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/context_budget.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/decision_packages.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/harness.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/markdown_preview.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/orders.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/policy.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/portfolio.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/research.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/runtime.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/runtime_mode.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/workflow_planner.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/application/workflow_routing.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/asgi.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/settings.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/static/tradingcodex_admin/favicon.svg +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/static/tradingcodex_web/app.js +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/static/vendor/htmx/htmx.min.js +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/activity.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/agent_skills.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/base.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/brokers.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/dashboard.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/decisions.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/fragments/role_inspector.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/fragments/topology_canvas.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/fragments/workspace_card.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/harness.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/orders.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/policy.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/portfolio.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/templates/web/starter_prompt.html +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/tradingcodex_service/wsgi.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/__init__.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/audit/files/.tradingcodex/audit/README.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/audit/files/trading/audit/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/audit/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.codex/config.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.codex/hooks/tradingcodex_hook.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.codex/hooks.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.codex/rules/tradingcodex.rules +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.tradingcodex/capabilities.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.tradingcodex/cli.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.tradingcodex/config.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.tradingcodex/policies/policy-bindings.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.tradingcodex/policies/principals.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/.tradingcodex/policies/roles.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/AGENTS.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/files/pyproject.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/codex-base/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/policies/access-policies.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/policies/restricted-list.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/approval_receipt.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/audit_event.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/evidence_pack.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/execution_result.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/fundamental_report.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/news_report.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/order_ticket.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/portfolio_review.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/postmortem_report.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/research_artifact.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/risk_report.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/technical_report.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/thesis.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/files/.tradingcodex/schemas/valuation.schema.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/enforcement-guardrails/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/execution-operator.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/fundamental-analyst.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/instrument-analyst.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/judgment-reviewer.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/macro-analyst.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/news-analyst.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/portfolio-manager.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/risk-manager.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/technical-analyst.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.codex/agents/valuation-analyst.toml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/files/.tradingcodex/mainagent/skill-change-proposals/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/fixed-subagents/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/guidance-guardrails/files/.tradingcodex/guidance/guardrails.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/guidance-guardrails/files/.tradingcodex/guidance/task-quality-checklist.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/guidance-guardrails/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/.tradingcodex/policies/information-barriers.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/.tradingcodex/secrets.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/approvals/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/forecasts/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/market-data/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/orders/approved/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/orders/draft/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/orders/executed/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/orders/rejected/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/portfolio/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/fundamental/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/instrument/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/macro/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/news/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/policy/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/portfolio/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/postmortem/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/risk/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/technical/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/reports/valuation/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/files/trading/research/.gitkeep +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/information-barriers/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/paper-trading/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/postmortem/files/.tradingcodex/workflows/postmortem.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/postmortem/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/automate-workflow/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/automate-workflow/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/plan-workflow/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/plan-workflow/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/postmortem/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/postmortem/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/strategy-creator/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/strategy-creator/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/tcx-server/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/tcx-server/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/tcx-workflow/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/tcx-workflow/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.agents/skills/tcx-workflow/references/decision-quality-spine.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/execution-operator/execute-paper-order/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/execution-operator/execute-paper-order/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/fundamental-analyst/fundamental-analysis/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/fundamental-analyst/fundamental-analysis/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/instrument-analyst/instrument-analysis/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/instrument-analyst/instrument-analysis/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/judgment-reviewer/agent-judgment-review/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/judgment-reviewer/agent-judgment-review/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/macro-analyst/macro-analysis/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/macro-analyst/macro-analysis/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/news-analyst/news-analysis/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/news-analyst/news-analysis/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/portfolio-manager/create-order-ticket/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/portfolio-manager/create-order-ticket/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/portfolio-manager/portfolio-review/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/portfolio-manager/portfolio-review/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/risk-manager/approve-order/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/risk-manager/approve-order/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/risk-manager/policy-review/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/risk-manager/policy-review/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/risk-manager/review-risk/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/risk-manager/review-risk/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/anti-overfit-validation/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/anti-overfit-validation/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/collect-evidence/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/collect-evidence/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/external-data-source-gate/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/external-data-source-gate/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/forecasting-discipline/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/forecasting-discipline/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/numeric-data-qc/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/numeric-data-qc/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/thesis-scenario-tree/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/shared/thesis-scenario-tree/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/technical-analyst/technical-analysis/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/technical-analyst/technical-analysis/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/valuation-analyst/valuation-review/SKILL.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/files/.tradingcodex/subagents/skills/valuation-analyst/valuation-review/agents/openai.yaml +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/repo-skills/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/stub-execution/module.json +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/tradingcodex-mcp/files/.tradingcodex/mcp/enforcer/README.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/tradingcodex-mcp/files/.tradingcodex/mcp/gateway/README.md +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/tradingcodex-mcp/files/.tradingcodex/mcp/server.py +0 -0
- {tradingcodex-0.3.2 → tradingcodex-0.3.4}/workspace_templates/modules/tradingcodex-mcp/module.json +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: tradingcodex
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.4
|
|
4
4
|
Summary: Agentic investment workflow harness for Codex-native research and service-gated execution checks.
|
|
5
5
|
Author: TradingCodex Authors
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -229,7 +229,7 @@ provide investment recommendations or guarantee returns.
|
|
|
229
229
|
| Status | Milestone |
|
|
230
230
|
| --- | --- |
|
|
231
231
|
| Shipped | Generated Codex workspace, fixed role roster, project MCP config, Django service plane, local web dashboard, Admin, Ninja API, file-native research memory, component registry, policy/audit primitives. |
|
|
232
|
-
| Current `0.3.
|
|
232
|
+
| Current `0.3.4` | Build Center customization, Codex MCP discovery/import, external MCP permission approval UX, head-manager research synthesis depth, flexible package/workspace update status, skipped-version Django migration smoke coverage, Codex-native Decision Packages, independent judgment-review gate, staged workflow planning, artifact-supervisor loop closure state, Evidence Run/Validation Cards, provider capability profiles, and Python `>=3.11,<3.15` support. |
|
|
233
233
|
| Next | Deeper validation scenarios, richer provider capability profiles, stronger generated-workspace smoke coverage, and improved artifact quality tooling. |
|
|
234
234
|
| Future | Separately governed verified adapters, hosted/managed services, enterprise policy/compliance packs, and broker-specific live providers only after explicit product, policy, adapter, and validation work. |
|
|
235
235
|
|
|
@@ -198,7 +198,7 @@ provide investment recommendations or guarantee returns.
|
|
|
198
198
|
| Status | Milestone |
|
|
199
199
|
| --- | --- |
|
|
200
200
|
| Shipped | Generated Codex workspace, fixed role roster, project MCP config, Django service plane, local web dashboard, Admin, Ninja API, file-native research memory, component registry, policy/audit primitives. |
|
|
201
|
-
| Current `0.3.
|
|
201
|
+
| Current `0.3.4` | Build Center customization, Codex MCP discovery/import, external MCP permission approval UX, head-manager research synthesis depth, flexible package/workspace update status, skipped-version Django migration smoke coverage, Codex-native Decision Packages, independent judgment-review gate, staged workflow planning, artifact-supervisor loop closure state, Evidence Run/Validation Cards, provider capability profiles, and Python `>=3.11,<3.15` support. |
|
|
202
202
|
| Next | Deeper validation scenarios, richer provider capability profiles, stronger generated-workspace smoke coverage, and improved artifact quality tooling. |
|
|
203
203
|
| Future | Separately governed verified adapters, hosted/managed services, enterprise policy/compliance packs, and broker-specific live providers only after explicit product, policy, adapter, and validation work. |
|
|
204
204
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
from django.contrib import admin
|
|
2
2
|
|
|
3
3
|
from apps.mcp.models import (
|
|
4
|
+
McpExternalPermissionRequest,
|
|
4
5
|
McpExternalTool,
|
|
5
6
|
McpExternalToolCall,
|
|
6
7
|
McpExternalToolPermission,
|
|
@@ -16,5 +17,6 @@ admin.site.register([
|
|
|
16
17
|
McpRouter,
|
|
17
18
|
McpExternalTool,
|
|
18
19
|
McpExternalToolPermission,
|
|
20
|
+
McpExternalPermissionRequest,
|
|
19
21
|
McpExternalToolCall,
|
|
20
22
|
])
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Generated by TradingCodex on 2026-07-06
|
|
2
|
+
|
|
3
|
+
import django.db.models.deletion
|
|
4
|
+
from django.db import migrations, models
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class Migration(migrations.Migration):
|
|
8
|
+
|
|
9
|
+
dependencies = [
|
|
10
|
+
("mcp", "0001_initial"),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
operations = [
|
|
14
|
+
migrations.CreateModel(
|
|
15
|
+
name="McpExternalPermissionRequest",
|
|
16
|
+
fields=[
|
|
17
|
+
("id", models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name="ID")),
|
|
18
|
+
("created_at", models.DateTimeField(auto_now_add=True)),
|
|
19
|
+
("updated_at", models.DateTimeField(auto_now=True)),
|
|
20
|
+
("router_name", models.CharField(max_length=160)),
|
|
21
|
+
("external_name", models.CharField(max_length=200)),
|
|
22
|
+
("principal_id", models.CharField(default="unknown", max_length=128)),
|
|
23
|
+
("role", models.CharField(blank=True, max_length=128)),
|
|
24
|
+
("workflow_run_id", models.CharField(blank=True, max_length=160)),
|
|
25
|
+
("request_hash", models.CharField(max_length=64)),
|
|
26
|
+
("arguments_summary", models.JSONField(blank=True, default=dict)),
|
|
27
|
+
("approval_scope", models.CharField(default="single_call", max_length=32)),
|
|
28
|
+
("status", models.CharField(default="pending", max_length=32)),
|
|
29
|
+
("reasons", models.JSONField(blank=True, default=list)),
|
|
30
|
+
("expires_at", models.DateTimeField(blank=True, null=True)),
|
|
31
|
+
("decided_by", models.CharField(blank=True, max_length=128)),
|
|
32
|
+
("decided_at", models.DateTimeField(blank=True, null=True)),
|
|
33
|
+
("decision_reason", models.TextField(blank=True)),
|
|
34
|
+
(
|
|
35
|
+
"external_tool",
|
|
36
|
+
models.ForeignKey(
|
|
37
|
+
blank=True,
|
|
38
|
+
null=True,
|
|
39
|
+
on_delete=django.db.models.deletion.SET_NULL,
|
|
40
|
+
related_name="permission_requests",
|
|
41
|
+
to="mcp.mcpexternaltool",
|
|
42
|
+
),
|
|
43
|
+
),
|
|
44
|
+
],
|
|
45
|
+
options={
|
|
46
|
+
"verbose_name": "external MCP permission request",
|
|
47
|
+
"verbose_name_plural": "external MCP permission requests",
|
|
48
|
+
"ordering": ["-created_at", "-id"],
|
|
49
|
+
},
|
|
50
|
+
),
|
|
51
|
+
]
|
|
@@ -130,6 +130,34 @@ class McpExternalToolPermission(models.Model):
|
|
|
130
130
|
return f"{self.external_tool.external_name} {self.principal_or_role} {self.decision}"
|
|
131
131
|
|
|
132
132
|
|
|
133
|
+
class McpExternalPermissionRequest(models.Model):
|
|
134
|
+
external_tool = models.ForeignKey(McpExternalTool, on_delete=models.SET_NULL, null=True, blank=True, related_name="permission_requests")
|
|
135
|
+
created_at = models.DateTimeField(auto_now_add=True)
|
|
136
|
+
updated_at = models.DateTimeField(auto_now=True)
|
|
137
|
+
router_name = models.CharField(max_length=160)
|
|
138
|
+
external_name = models.CharField(max_length=200)
|
|
139
|
+
principal_id = models.CharField(max_length=128, default="unknown")
|
|
140
|
+
role = models.CharField(max_length=128, blank=True)
|
|
141
|
+
workflow_run_id = models.CharField(max_length=160, blank=True)
|
|
142
|
+
request_hash = models.CharField(max_length=64)
|
|
143
|
+
arguments_summary = models.JSONField(default=dict, blank=True)
|
|
144
|
+
approval_scope = models.CharField(max_length=32, default="single_call")
|
|
145
|
+
status = models.CharField(max_length=32, default="pending")
|
|
146
|
+
reasons = models.JSONField(default=list, blank=True)
|
|
147
|
+
expires_at = models.DateTimeField(null=True, blank=True)
|
|
148
|
+
decided_by = models.CharField(max_length=128, blank=True)
|
|
149
|
+
decided_at = models.DateTimeField(null=True, blank=True)
|
|
150
|
+
decision_reason = models.TextField(blank=True)
|
|
151
|
+
|
|
152
|
+
class Meta:
|
|
153
|
+
ordering = ["-created_at", "-id"]
|
|
154
|
+
verbose_name = "external MCP permission request"
|
|
155
|
+
verbose_name_plural = "external MCP permission requests"
|
|
156
|
+
|
|
157
|
+
def __str__(self) -> str:
|
|
158
|
+
return f"{self.router_name}:{self.external_name} {self.status}"
|
|
159
|
+
|
|
160
|
+
|
|
133
161
|
class McpExternalToolCall(models.Model):
|
|
134
162
|
created_at = models.DateTimeField(auto_now_add=True)
|
|
135
163
|
external_tool = models.ForeignKey(McpExternalTool, on_delete=models.SET_NULL, null=True, blank=True, related_name="calls")
|
|
@@ -8,12 +8,14 @@ import shlex
|
|
|
8
8
|
import subprocess
|
|
9
9
|
import time
|
|
10
10
|
import urllib.request
|
|
11
|
+
from datetime import timedelta
|
|
11
12
|
from typing import Any
|
|
12
13
|
|
|
13
14
|
from django.utils import timezone
|
|
14
15
|
from django.db.models import QuerySet
|
|
15
16
|
|
|
16
17
|
from apps.mcp.models import (
|
|
18
|
+
McpExternalPermissionRequest,
|
|
17
19
|
McpExternalTool,
|
|
18
20
|
McpExternalToolCall,
|
|
19
21
|
McpExternalToolPermission,
|
|
@@ -53,6 +55,8 @@ RESEARCH_ROLES = {
|
|
|
53
55
|
}
|
|
54
56
|
ACCOUNT_READ_ROLES = {"head-manager", "portfolio-manager", "risk-manager", "execution-operator"}
|
|
55
57
|
PORTFOLIO_STATE_ROLES = {"portfolio-manager", "risk-manager"}
|
|
58
|
+
USER_APPROVAL_CATEGORIES = {"account_read", "portfolio_state", "research_write", "workflow_prompt", "execution"}
|
|
59
|
+
SENSITIVE_ARGUMENT_RE = re.compile(r"secret|credential|password|api[_-]?key|token", flags=re.I)
|
|
56
60
|
|
|
57
61
|
|
|
58
62
|
def set_mcp_tools_enabled(queryset: QuerySet[McpToolDefinition], enabled: bool, actor: str = "admin") -> int:
|
|
@@ -355,8 +359,25 @@ def evaluate_external_mcp_proxy_call(
|
|
|
355
359
|
arguments: dict[str, Any] | None = None,
|
|
356
360
|
actor: str = "mcp-proxy",
|
|
357
361
|
) -> dict[str, Any]:
|
|
362
|
+
arguments = arguments or {}
|
|
358
363
|
reasons = external_tool_denial_reasons(tool, principal_id)
|
|
359
|
-
|
|
364
|
+
request_hash = stable_hash(arguments)
|
|
365
|
+
permission_request = None
|
|
366
|
+
if not reasons and _external_tool_requires_user_approval(tool) and not _approved_external_permission(tool, principal_id, request_hash):
|
|
367
|
+
role = role_for_principal_id(principal_id)
|
|
368
|
+
permission_request = _create_or_reuse_permission_request(
|
|
369
|
+
tool,
|
|
370
|
+
principal_id=principal_id,
|
|
371
|
+
role=role,
|
|
372
|
+
request_hash=request_hash,
|
|
373
|
+
arguments=arguments,
|
|
374
|
+
workflow_run_id=str(arguments.get("workflow_run_id") or ""),
|
|
375
|
+
reasons=["user permission required for external MCP call"],
|
|
376
|
+
)
|
|
377
|
+
reasons = ["user permission required for external MCP call"]
|
|
378
|
+
decision = "approval_required"
|
|
379
|
+
else:
|
|
380
|
+
decision = "allow" if not reasons else "deny"
|
|
360
381
|
result = {
|
|
361
382
|
"decision": decision,
|
|
362
383
|
"reasons": reasons,
|
|
@@ -368,6 +389,7 @@ def evaluate_external_mcp_proxy_call(
|
|
|
368
389
|
"canonical_capability": tool.canonical_capability,
|
|
369
390
|
"adapter_call_allowed": decision == "allow" and tool.proxy_mode in SERVICE_PROXY_MODES,
|
|
370
391
|
"direct_proxy_allowed": decision == "allow" and tool.proxy_mode in READ_ONLY_PROXY_MODES,
|
|
392
|
+
"permission_request": serialize_permission_request(permission_request) if permission_request else None,
|
|
371
393
|
"db_canonical": True,
|
|
372
394
|
"workspace_context": workspace_context_payload(workspace_root),
|
|
373
395
|
}
|
|
@@ -379,16 +401,104 @@ def evaluate_external_mcp_proxy_call(
|
|
|
379
401
|
proxy_mode=tool.proxy_mode,
|
|
380
402
|
decision=decision,
|
|
381
403
|
reasons=reasons,
|
|
382
|
-
request=arguments
|
|
404
|
+
request=arguments,
|
|
383
405
|
response=result,
|
|
384
|
-
request_hash=
|
|
406
|
+
request_hash=request_hash,
|
|
385
407
|
result_hash=stable_hash(result),
|
|
386
408
|
workspace_context=result["workspace_context"],
|
|
387
409
|
)
|
|
388
|
-
|
|
410
|
+
audit_action = "external_mcp.proxy_allowed" if decision == "allow" else "external_mcp.proxy_permission_required" if decision == "approval_required" else "external_mcp.proxy_denied"
|
|
411
|
+
_audit(audit_action, {"tool": str(tool), "reasons": reasons}, actor)
|
|
389
412
|
return result
|
|
390
413
|
|
|
391
414
|
|
|
415
|
+
def list_external_mcp_permission_requests(workspace_root: Any = None, args: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
416
|
+
ensure_runtime_database(workspace_root)
|
|
417
|
+
_expire_external_mcp_permission_requests()
|
|
418
|
+
args = args or {}
|
|
419
|
+
queryset = McpExternalPermissionRequest.objects.select_related("external_tool").all()
|
|
420
|
+
status = str(args.get("status") or "pending")
|
|
421
|
+
if status and status != "all":
|
|
422
|
+
queryset = queryset.filter(status=status)
|
|
423
|
+
if args.get("principal_id"):
|
|
424
|
+
queryset = queryset.filter(principal_id=str(args["principal_id"]))
|
|
425
|
+
if args.get("router_name") or args.get("name"):
|
|
426
|
+
queryset = queryset.filter(router_name=str(args.get("router_name") or args.get("name")))
|
|
427
|
+
limit = max(1, min(int(args.get("limit") or 50), 200))
|
|
428
|
+
return {
|
|
429
|
+
"status": "ok",
|
|
430
|
+
"requests": [serialize_permission_request(item) for item in queryset[:limit]],
|
|
431
|
+
"count": queryset.count(),
|
|
432
|
+
"workspace_context": workspace_context_payload(workspace_root),
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
|
|
436
|
+
def approve_external_mcp_permission_request(workspace_root: Any, args: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
437
|
+
ensure_runtime_database(workspace_root)
|
|
438
|
+
_expire_external_mcp_permission_requests()
|
|
439
|
+
args = args or {}
|
|
440
|
+
request = resolve_external_mcp_permission_request(args)
|
|
441
|
+
if request.status != "pending":
|
|
442
|
+
raise ValueError(f"external MCP permission request is not pending: {request.status}")
|
|
443
|
+
request.status = "approved"
|
|
444
|
+
request.decided_by = str(args.get("principal_id") or args.get("decided_by") or "user")
|
|
445
|
+
request.decided_at = timezone.now()
|
|
446
|
+
request.decision_reason = str(args.get("reason") or "")
|
|
447
|
+
request.save(update_fields=["status", "decided_by", "decided_at", "decision_reason", "updated_at"])
|
|
448
|
+
_audit("external_mcp.permission_approved", {"request_id": request.id, "tool": f"{request.router_name}:{request.external_name}"}, request.decided_by)
|
|
449
|
+
return {"status": "approved", "request": serialize_permission_request(request), "workspace_context": workspace_context_payload(workspace_root)}
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
def deny_external_mcp_permission_request(workspace_root: Any, args: dict[str, Any] | None = None) -> dict[str, Any]:
|
|
453
|
+
ensure_runtime_database(workspace_root)
|
|
454
|
+
_expire_external_mcp_permission_requests()
|
|
455
|
+
args = args or {}
|
|
456
|
+
request = resolve_external_mcp_permission_request(args)
|
|
457
|
+
if request.status != "pending":
|
|
458
|
+
raise ValueError(f"external MCP permission request is not pending: {request.status}")
|
|
459
|
+
request.status = "denied"
|
|
460
|
+
request.decided_by = str(args.get("principal_id") or args.get("decided_by") or "user")
|
|
461
|
+
request.decided_at = timezone.now()
|
|
462
|
+
request.decision_reason = str(args.get("reason") or "")
|
|
463
|
+
request.save(update_fields=["status", "decided_by", "decided_at", "decision_reason", "updated_at"])
|
|
464
|
+
_audit("external_mcp.permission_denied", {"request_id": request.id, "tool": f"{request.router_name}:{request.external_name}"}, request.decided_by)
|
|
465
|
+
return {"status": "denied", "request": serialize_permission_request(request), "workspace_context": workspace_context_payload(workspace_root)}
|
|
466
|
+
|
|
467
|
+
|
|
468
|
+
def resolve_external_mcp_permission_request(args: dict[str, Any]) -> McpExternalPermissionRequest:
|
|
469
|
+
request_id = args.get("request_id") or args.get("id")
|
|
470
|
+
if request_id in (None, ""):
|
|
471
|
+
raise ValueError("external MCP permission request requires request_id")
|
|
472
|
+
request = McpExternalPermissionRequest.objects.select_related("external_tool").filter(pk=int(request_id)).first()
|
|
473
|
+
if request is None:
|
|
474
|
+
raise ValueError(f"external MCP permission request not found: {request_id}")
|
|
475
|
+
return request
|
|
476
|
+
|
|
477
|
+
|
|
478
|
+
def serialize_permission_request(request: McpExternalPermissionRequest | None) -> dict[str, Any] | None:
|
|
479
|
+
if request is None:
|
|
480
|
+
return None
|
|
481
|
+
return {
|
|
482
|
+
"id": request.id,
|
|
483
|
+
"created_at": request.created_at.isoformat() if request.created_at else "",
|
|
484
|
+
"updated_at": request.updated_at.isoformat() if request.updated_at else "",
|
|
485
|
+
"router_name": request.router_name,
|
|
486
|
+
"external_name": request.external_name,
|
|
487
|
+
"principal_id": request.principal_id,
|
|
488
|
+
"role": request.role,
|
|
489
|
+
"workflow_run_id": request.workflow_run_id,
|
|
490
|
+
"request_hash": request.request_hash,
|
|
491
|
+
"arguments_summary": request.arguments_summary,
|
|
492
|
+
"approval_scope": request.approval_scope,
|
|
493
|
+
"status": request.status,
|
|
494
|
+
"reasons": list(request.reasons or []),
|
|
495
|
+
"expires_at": request.expires_at.isoformat() if request.expires_at else "",
|
|
496
|
+
"decided_by": request.decided_by,
|
|
497
|
+
"decided_at": request.decided_at.isoformat() if request.decided_at else "",
|
|
498
|
+
"decision_reason": request.decision_reason,
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
|
|
392
502
|
def external_tool_denial_reasons(tool: McpExternalTool, principal_id: str) -> list[str]:
|
|
393
503
|
reasons: list[str] = []
|
|
394
504
|
role = role_for_principal_id(principal_id)
|
|
@@ -412,6 +522,79 @@ def external_tool_denial_reasons(tool: McpExternalTool, principal_id: str) -> li
|
|
|
412
522
|
return list(dict.fromkeys(reasons))
|
|
413
523
|
|
|
414
524
|
|
|
525
|
+
def _external_tool_requires_user_approval(tool: McpExternalTool) -> bool:
|
|
526
|
+
if tool.category in USER_APPROVAL_CATEGORIES:
|
|
527
|
+
return True
|
|
528
|
+
return tool.sensitivity not in {"public", ""} or tool.risk_level in {"write", "approval", "execution"}
|
|
529
|
+
|
|
530
|
+
|
|
531
|
+
def _approved_external_permission(tool: McpExternalTool, principal_id: str, request_hash: str) -> bool:
|
|
532
|
+
now = timezone.now()
|
|
533
|
+
return McpExternalPermissionRequest.objects.filter(
|
|
534
|
+
external_tool=tool,
|
|
535
|
+
principal_id=principal_id,
|
|
536
|
+
request_hash=request_hash,
|
|
537
|
+
status="approved",
|
|
538
|
+
).filter(expires_at__gt=now).exists()
|
|
539
|
+
|
|
540
|
+
|
|
541
|
+
def _create_or_reuse_permission_request(
|
|
542
|
+
tool: McpExternalTool,
|
|
543
|
+
*,
|
|
544
|
+
principal_id: str,
|
|
545
|
+
role: str,
|
|
546
|
+
request_hash: str,
|
|
547
|
+
arguments: dict[str, Any],
|
|
548
|
+
workflow_run_id: str = "",
|
|
549
|
+
reasons: list[str] | None = None,
|
|
550
|
+
) -> McpExternalPermissionRequest:
|
|
551
|
+
now = timezone.now()
|
|
552
|
+
_expire_external_mcp_permission_requests(now)
|
|
553
|
+
request = McpExternalPermissionRequest.objects.filter(
|
|
554
|
+
external_tool=tool,
|
|
555
|
+
principal_id=principal_id,
|
|
556
|
+
request_hash=request_hash,
|
|
557
|
+
status="pending",
|
|
558
|
+
expires_at__gt=now,
|
|
559
|
+
).first()
|
|
560
|
+
if request is not None:
|
|
561
|
+
return request
|
|
562
|
+
return McpExternalPermissionRequest.objects.create(
|
|
563
|
+
external_tool=tool,
|
|
564
|
+
router_name=tool.router.name,
|
|
565
|
+
external_name=tool.external_name,
|
|
566
|
+
principal_id=principal_id,
|
|
567
|
+
role=role,
|
|
568
|
+
workflow_run_id=workflow_run_id,
|
|
569
|
+
request_hash=request_hash,
|
|
570
|
+
arguments_summary=_summarize_arguments(arguments),
|
|
571
|
+
reasons=reasons or [],
|
|
572
|
+
expires_at=now + timedelta(hours=24),
|
|
573
|
+
)
|
|
574
|
+
|
|
575
|
+
|
|
576
|
+
def _expire_external_mcp_permission_requests(now: Any = None) -> None:
|
|
577
|
+
now = now or timezone.now()
|
|
578
|
+
McpExternalPermissionRequest.objects.filter(status="pending", expires_at__lte=now).update(status="expired", updated_at=now)
|
|
579
|
+
|
|
580
|
+
|
|
581
|
+
def _summarize_arguments(arguments: dict[str, Any]) -> dict[str, Any]:
|
|
582
|
+
summary: dict[str, Any] = {}
|
|
583
|
+
for key, value in sorted((arguments or {}).items()):
|
|
584
|
+
if SENSITIVE_ARGUMENT_RE.search(str(key)):
|
|
585
|
+
summary[str(key)] = "<redacted>"
|
|
586
|
+
elif isinstance(value, str | int | float | bool) or value is None:
|
|
587
|
+
text = str(value)
|
|
588
|
+
summary[str(key)] = text if len(text) <= 120 else text[:117] + "..."
|
|
589
|
+
elif isinstance(value, list):
|
|
590
|
+
summary[str(key)] = f"list[{len(value)}]"
|
|
591
|
+
elif isinstance(value, dict):
|
|
592
|
+
summary[str(key)] = f"object[{len(value)}]"
|
|
593
|
+
else:
|
|
594
|
+
summary[str(key)] = type(value).__name__
|
|
595
|
+
return summary
|
|
596
|
+
|
|
597
|
+
|
|
415
598
|
def resolve_external_mcp_router(args: dict[str, Any]) -> McpRouter:
|
|
416
599
|
router_id = args.get("router_id") or args.get("connection_id")
|
|
417
600
|
name = args.get("name") or args.get("router_name")
|
|
@@ -64,7 +64,7 @@ If these layers disagree, treat `docs/` as the durable product intent and fix th
|
|
|
64
64
|
| [interfaces-and-surfaces.md](./interfaces-and-surfaces.md) | Product web, Django Admin, Django Ninja API, MCP boundary, CLI, generated wrapper behavior, and external MCP surface. |
|
|
65
65
|
| [generated-workspaces.md](./generated-workspaces.md) | `tcx attach`, `tcx init`, `tcx update`, generated files, project-scoped MCP config, hooks, workspace provenance, profile scope, and template rules. |
|
|
66
66
|
| [validation-and-test-plan.md](./validation-and-test-plan.md) | Required validation commands, unit/API/generator/smoke coverage, MCP smokes, broker provider smokes, routing scenarios, and release-sensitive checks. |
|
|
67
|
-
| [deployment.md](./deployment.md) | PyPI
|
|
67
|
+
| [deployment.md](./deployment.md) | PyPI release process, CI/CD, Trusted Publishing, installer/update policy, versioning, and what is not deployed. |
|
|
68
68
|
| [licensing-and-commercialization.md](./licensing-and-commercialization.md) | Apache-2.0 open-core boundary, generated workspace ownership, contributions, trademark posture, and legal review needs. |
|
|
69
69
|
|
|
70
70
|
## Change-To-Docs Map
|
|
@@ -34,9 +34,6 @@ Use Python 3.11 for release build verification and keep CI green across the
|
|
|
34
34
|
supported range. The package metadata requires `>=3.11,<3.15`, and CI runs on
|
|
35
35
|
Python 3.11, 3.12, 3.13, and 3.14.
|
|
36
36
|
|
|
37
|
-
Create separate PyPI and TestPyPI accounts. TestPyPI is a separate service and
|
|
38
|
-
does not share login state with PyPI.
|
|
39
|
-
|
|
40
37
|
Configure Trusted Publishing before the first upload. Do not store long-lived
|
|
41
38
|
PyPI API tokens in GitHub repository secrets unless Trusted Publishing is not
|
|
42
39
|
available.
|
|
@@ -46,12 +43,9 @@ Trusted Publisher settings:
|
|
|
46
43
|
| Index | Project | Owner | Repository | Workflow | Environment |
|
|
47
44
|
| --- | --- | --- | --- | --- | --- |
|
|
48
45
|
| PyPI | `tradingcodex` | repository owner/org | repository name | `release.yml` | `pypi` |
|
|
49
|
-
| TestPyPI | `tradingcodex` | repository owner/org | repository name | `release.yml` | `testpypi` |
|
|
50
|
-
|
|
51
|
-
On GitHub, create both environments:
|
|
52
46
|
|
|
53
|
-
|
|
54
|
-
|
|
47
|
+
On GitHub, create the `pypi` environment and require manual approval before
|
|
48
|
+
deployment.
|
|
55
49
|
|
|
56
50
|
## Local Build Verification
|
|
57
51
|
|
|
@@ -101,27 +95,25 @@ It runs on pull requests and pushes to `main` or `develop`:
|
|
|
101
95
|
- builds the package for validation only
|
|
102
96
|
- validates distribution metadata with `twine check`
|
|
103
97
|
|
|
104
|
-
The CI workflow never uploads to
|
|
105
|
-
|
|
98
|
+
The CI workflow never uploads to PyPI. Pushes to `main` or `develop` run tests
|
|
99
|
+
and packaging checks only.
|
|
106
100
|
|
|
107
101
|
Release automation is defined in `.github/workflows/release.yml` and appears as
|
|
108
102
|
`Manual Release` in GitHub Actions.
|
|
109
103
|
|
|
110
104
|
The release workflow is manual-only. Branch pushes and tag pushes must not
|
|
111
|
-
publish package artifacts to
|
|
105
|
+
publish package artifacts to PyPI.
|
|
112
106
|
|
|
113
107
|
The release workflow has additional guardrails:
|
|
114
108
|
|
|
115
109
|
- publication requires `workflow_dispatch`
|
|
116
110
|
- PyPI publication is allowed only from the `main` branch
|
|
117
|
-
- TestPyPI and PyPI publication must be run as separate manual workflow runs
|
|
118
111
|
- concurrent release runs on the same ref are serialized instead of cancelled
|
|
119
112
|
|
|
120
|
-
Manual `workflow_dispatch` can publish to
|
|
121
|
-
`publish_testpypi=true`, and to PyPI when `publish_pypi=true`.
|
|
113
|
+
Manual `workflow_dispatch` can publish to PyPI when `publish_pypi=true`.
|
|
122
114
|
|
|
123
|
-
Keep
|
|
124
|
-
|
|
115
|
+
Keep `publish_pypi=false` when the run should only build and verify
|
|
116
|
+
distributions.
|
|
125
117
|
|
|
126
118
|
The workflow uses PyPI Trusted Publishing. The publish jobs request only an
|
|
127
119
|
OIDC token through `id-token: write`; they do not require API-token secrets.
|
|
@@ -134,32 +126,6 @@ and download do not depend on the deprecated Node.js 20 action runtime.
|
|
|
134
126
|
`tcx update` applies central DB migrations before the updated workspace is used.
|
|
135
127
|
Product flows create, check, approve, and submit `OrderTicket` records directly.
|
|
136
128
|
|
|
137
|
-
## TestPyPI Release
|
|
138
|
-
|
|
139
|
-
Use TestPyPI before the first public PyPI release and after packaging changes.
|
|
140
|
-
|
|
141
|
-
1. Confirm the local build verification steps pass.
|
|
142
|
-
2. Run the `Manual Release` workflow manually with `publish_testpypi=true`.
|
|
143
|
-
3. Install from TestPyPI in a clean environment.
|
|
144
|
-
|
|
145
|
-
Example:
|
|
146
|
-
|
|
147
|
-
```bash
|
|
148
|
-
python3.11 -m venv /tmp/tcx-testpypi
|
|
149
|
-
/tmp/tcx-testpypi/bin/pip install \
|
|
150
|
-
--index-url https://test.pypi.org/simple/ \
|
|
151
|
-
--extra-index-url https://pypi.org/simple/ \
|
|
152
|
-
tradingcodex==0.3.2
|
|
153
|
-
rm -rf /tmp/tcx-testpypi-smoke
|
|
154
|
-
mkdir -p /tmp/tcx-testpypi-smoke
|
|
155
|
-
cd /tmp/tcx-testpypi-smoke
|
|
156
|
-
/tmp/tcx-testpypi/bin/tcx attach .
|
|
157
|
-
./tcx doctor
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
`--extra-index-url` is used because dependencies such as Django may not be
|
|
161
|
-
available on TestPyPI.
|
|
162
|
-
|
|
163
129
|
## PyPI Release
|
|
164
130
|
|
|
165
131
|
Before pushing the release tag:
|
|
@@ -168,7 +134,6 @@ Before pushing the release tag:
|
|
|
168
134
|
- verify `README.md` describes execution as service-gated
|
|
169
135
|
- verify docs mention that live broker execution requires installed providers and explicit gates
|
|
170
136
|
- run local build verification
|
|
171
|
-
- run a TestPyPI release when packaging changed
|
|
172
137
|
|
|
173
138
|
Then create or update the GitHub release/tag as needed, and run the
|
|
174
139
|
`Manual Release` workflow manually with `publish_pypi=true`. Do not rely on tag push for
|
|
@@ -178,7 +143,7 @@ After the PyPI workflow completes:
|
|
|
178
143
|
|
|
179
144
|
```bash
|
|
180
145
|
python3.11 -m venv /tmp/tcx-pypi
|
|
181
|
-
/tmp/tcx-pypi/bin/pip install tradingcodex==0.3.
|
|
146
|
+
/tmp/tcx-pypi/bin/pip install tradingcodex==0.3.4
|
|
182
147
|
rm -rf /tmp/tcx-pypi-smoke
|
|
183
148
|
mkdir -p /tmp/tcx-pypi-smoke
|
|
184
149
|
cd /tmp/tcx-pypi-smoke
|
|
@@ -279,7 +244,13 @@ Use PEP 440 versions:
|
|
|
279
244
|
state fixes after `0.3.0`
|
|
280
245
|
- `0.3.2` for brief research chat replies with saved head-manager synthesis
|
|
281
246
|
reports after `0.3.1`
|
|
282
|
-
-
|
|
247
|
+
- `0.3.3` for flexible update status across package/workspace drift,
|
|
248
|
+
skipped-version Django migration smoke coverage, and PyPI-only release flow
|
|
249
|
+
after `0.3.2`
|
|
250
|
+
- `0.3.4` for Build Center customization, Codex MCP discovery/import, external
|
|
251
|
+
MCP permission approval UX, and head-manager research synthesis depth after
|
|
252
|
+
`0.3.3`
|
|
253
|
+
- later patch releases for compatible fixes after `0.3.4`
|
|
283
254
|
- pre-releases such as `0.4.0a1`, `0.4.0b1`, or `0.4.0rc1` when preparing
|
|
284
255
|
the next minor contract
|
|
285
256
|
|
|
@@ -101,7 +101,7 @@ Generated workspaces contain:
|
|
|
101
101
|
- an immutable workspace manifest at `.tradingcodex/workspace.json`
|
|
102
102
|
- root `head-manager` identity loaded from `.codex/prompts/base_instructions/head-manager.md` through `.codex/config.toml` `model_instructions_file`
|
|
103
103
|
- sectioned Markdown base-instruction format for `head-manager`, including `# How you work`, TradingCodex guardrails, and tool guidelines
|
|
104
|
-
- Codex-style operating style in the root `head-manager` prompt: scoped `AGENTS.md` handling, concise preambles, selective planning, `rg`-first search, `apply_patch` edits, focused validation, dirty-worktree respect, concise maintenance handoffs, and brief chat replies that point to saved head-manager synthesis reports once accepted artifacts exist
|
|
104
|
+
- Codex-style operating style in the root `head-manager` prompt: scoped `AGENTS.md` handling, concise preambles, selective planning, `rg`-first search, `apply_patch` edits, focused validation, dirty-worktree respect, concise maintenance handoffs, and brief chat replies that point to saved head-manager synthesis reports once accepted artifacts exist without making the saved research report shallow
|
|
105
105
|
- instruction/skill separation: root `head-manager` instructions own identity, durable safety boundaries, fail-closed dispatch, role boundaries, skill routing, optional-skill management, and approved action boundaries; fixed subagent TOML files own standing role identity, MCP/tool config, artifact walls, and always-on prohibitions; repo skills are dependency-light capability procedures for workflow maps, compact assignment-envelope templates, optional skill file management, quality gates, synthesis, and postmortems, without declaring role ownership or direct inter-skill call chains
|
|
106
106
|
- no-overlap handoff contract: each role owns its specialist question, downstream roles consume accepted artifacts, and missing/stale/weak upstream work returns `revise`, `blocked`, or `waiting` instead of being silently redone by another role
|
|
107
107
|
- validated staged workflow plan: hook intake hints are not binding; `$tcx-workflow`
|
|
@@ -158,6 +158,7 @@ Generated workspaces contain:
|
|
|
158
158
|
- fixed subagent `nickname_candidates` set to a single item matching the exact role `name`
|
|
159
159
|
- fixed subagent identities kept in `.codex/agents/*.toml` `developer_instructions`, as required by Codex custom agent files
|
|
160
160
|
- project-local additional agent instructions under `.tradingcodex/agent-instructions/<role>.md`; projection appends them after generated default instructions for `head-manager` and fixed subagents
|
|
161
|
+
- workspace customization preferences under `.tradingcodex/user/customization.json`, merged over global defaults in `~/.tradingcodex/preferences/customization.json`; these files store UX/config metadata and never raw credentials
|
|
161
162
|
- twenty-six core repo skills across project-scope mainagent skills and subagent skill directories, each with `SKILL.md` frontmatter for document metadata and UI metadata when projected
|
|
162
163
|
- decision-quality skill bundles for forecasting discipline, thesis scenario
|
|
163
164
|
trees, numeric data QC, and anti-overfit validation, plus role-owned
|
|
@@ -186,6 +187,12 @@ ownership comes from the Python component registry and is exported into
|
|
|
186
187
|
Agent and skill ownership comes from the Python agent registry and is projected
|
|
187
188
|
into Codex-readable agent TOML plus generated agent/skill indexes.
|
|
188
189
|
|
|
190
|
+
User-configured Codex MCP servers are discovered from project and root Codex
|
|
191
|
+
config, then imported into TradingCodex External MCP Gate before use. Generated
|
|
192
|
+
project config should not expose external broker/data MCP tools directly to
|
|
193
|
+
subagents. TradingCodex writes Codex MCP config only inside explicit managed
|
|
194
|
+
blocks and leaves user-owned config outside those blocks untouched.
|
|
195
|
+
|
|
189
196
|
## Attach-First UX
|
|
190
197
|
|
|
191
198
|
TradingCodex is installed globally once, then attached to the workspace where
|
|
@@ -250,8 +257,9 @@ user-terminal workspace-only path:
|
|
|
250
257
|
step. If startup health reports `update_status.workspace_update_allowed=true`,
|
|
251
258
|
`head-manager` should tell the user to run
|
|
252
259
|
`update_status.workspace_update_command` from their terminal. If startup health
|
|
253
|
-
reports `update_status.package_update_required_first=true`,
|
|
254
|
-
|
|
260
|
+
reports `update_status.package_update_required_first=true`, including when the
|
|
261
|
+
generated workspace and installed wrapper both match an older release, package
|
|
262
|
+
refresh is also a user-terminal action, normally:
|
|
255
263
|
|
|
256
264
|
```bash
|
|
257
265
|
uvx --refresh --from tradingcodex tcx update .
|
|
@@ -366,7 +374,10 @@ must explain the two supported paths: switch Codex to full access and enable
|
|
|
366
374
|
TradingCodex build mode, or run the recommended `update_status.command` from a
|
|
367
375
|
terminal. Self-update is allowed only when Codex full access and explicit
|
|
368
376
|
workspace build mode are both active and the user asks for the update. After
|
|
369
|
-
self-update, `head-manager` stops and tells the user to restart Codex.
|
|
377
|
+
self-update, `head-manager` stops and tells the user to restart Codex. If a
|
|
378
|
+
same-DB service is already running with a newer TradingCodex version than the
|
|
379
|
+
current wrapper, startup health treats that service version as an update hint
|
|
380
|
+
and should recommend package/workspace refresh before service stop.
|
|
370
381
|
|
|
371
382
|
Build mode is per workspace and explicit:
|
|
372
383
|
|
|
@@ -50,6 +50,9 @@ Routes:
|
|
|
50
50
|
- `/integrations/mcp/` Data Sources surface for External MCP Gate registry,
|
|
51
51
|
source connection checks, manual discovery import, available action review,
|
|
52
52
|
role scopes, and audited dry-run decisions
|
|
53
|
+
- `/build/` Build Center for build-mode status, Codex config MCP discovery,
|
|
54
|
+
managed MCP config writes, agent customization summary, and pending external
|
|
55
|
+
MCP permission requests
|
|
53
56
|
|
|
54
57
|
Direct diagnostic routes may remain for local operators, but they are not part
|
|
55
58
|
of the primary product navigation:
|
|
@@ -147,6 +150,12 @@ primary web entrypoint. When present, it is server-rendered SVG/HTML and shows:
|
|
|
147
150
|
- The product web app can register external MCP connections, import discovery
|
|
148
151
|
metadata, review available actions/resources, set role scopes, and audit
|
|
149
152
|
dry-run decisions. It must not expose raw external tools directly to Codex.
|
|
153
|
+
- The product web app can discover project/root Codex MCP config and write
|
|
154
|
+
only TradingCodex managed MCP blocks when build mode and Codex full access
|
|
155
|
+
are active. It must not rewrite user-owned config outside managed blocks.
|
|
156
|
+
- The product web app can approve or deny pending external MCP permission
|
|
157
|
+
requests; this is user consent for proxy evaluation, not order or execution
|
|
158
|
+
authorization.
|
|
150
159
|
- Execution-sensitive actions remain behind TradingCodex MCP and service-layer
|
|
151
160
|
policy, approval, duplicate-request, connection, and audit checks.
|
|
152
161
|
|
|
@@ -355,6 +364,7 @@ Top-level commands:
|
|
|
355
364
|
- `tcx research create|append|get|list|search|export|run-card|validation-card`
|
|
356
365
|
- `tcx policy simulate`
|
|
357
366
|
- `tcx db status|path|migrate`
|
|
367
|
+
- `tcx build status|codex-mcp|permission`
|
|
358
368
|
- `tcx mcp call <tool> [tool args]`
|
|
359
369
|
- `tcx mcp ledger [--tool <name>] [--principal <id>] [--status ok]`
|
|
360
370
|
- `tcx mcp install-global --safe`
|
|
@@ -371,6 +381,7 @@ Generated workspace wrapper commands:
|
|
|
371
381
|
- `./tcx update status [--json]`
|
|
372
382
|
- `./tcx mode status`
|
|
373
383
|
- `./tcx mode set build --reason "<reason>"`
|
|
384
|
+
- `./tcx build status|codex-mcp|permission`
|
|
374
385
|
- `./tcx mode set operate`
|
|
375
386
|
- `./tcx connectors status`
|
|
376
387
|
- `./tcx connectors providers`
|
|
@@ -160,7 +160,9 @@ broader checks, respect for dirty worktrees, and concise maintenance handoffs.
|
|
|
160
160
|
Investment synthesis stores depth in a workspace Markdown report: after
|
|
161
161
|
accepted artifacts exist, `head-manager` should save the full synthesis under
|
|
162
162
|
`trading/reports/head-manager/` and keep the chat reply brief with the report
|
|
163
|
-
path, 1-3 key takeaways, and next allowed action.
|
|
163
|
+
path, 1-3 key takeaways, and next allowed action. The brief chat handoff must
|
|
164
|
+
not compress the saved research artifact; the Markdown report remains the
|
|
165
|
+
detailed user-facing research output.
|
|
164
166
|
|
|
165
167
|
This operating style is a working discipline, not an investment permission.
|
|
166
168
|
It does not weaken the dispatch gate, role-owned skill boundary, approved action
|
|
@@ -395,7 +397,8 @@ posture, or core skill behavior.
|
|
|
395
397
|
- Once accepted artifacts exist, head-manager final synthesis should be saved
|
|
396
398
|
as `trading/reports/head-manager/synthesis-<workflow_run_id>.md` through the
|
|
397
399
|
research artifact path. The chat reply should stay brief and point to that
|
|
398
|
-
report instead of pasting the full synthesis
|
|
400
|
+
report instead of pasting the full synthesis, but the report itself should
|
|
401
|
+
remain detailed enough to stand alone.
|
|
399
402
|
- `plan-workflow` mandates and `automate-workflow` automation summaries follow the same user-language rule.
|
|
400
403
|
- When selecting an exact fixed role with Codex `spawn_agent`, do not combine `agent_type` with full-history forking. Use a compact assignment envelope on the first attempt and no model/reasoning overrides.
|
|
401
404
|
- Workflow consent stays separate from explicit user constraints. Consent to orchestrate or use subagents allows dispatch, but it is not itself an analytical constraint.
|
|
@@ -137,6 +137,14 @@ External MCP permission is not execution authorization. Even if an external
|
|
|
137
137
|
broker order tool is present and reviewed, order submission must still pass the
|
|
138
138
|
TradingCodex order-ticket, approval, duplicate-request, connection, and audit lifecycle.
|
|
139
139
|
|
|
140
|
+
Reviewed external MCP calls that expose private account state, write research
|
|
141
|
+
state, use workflow prompts, or map to execution require an explicit user
|
|
142
|
+
permission request before proxy evaluation returns `allow`. The request is
|
|
143
|
+
stored as pending service-layer state and surfaced through Build Center,
|
|
144
|
+
`tcx build permission list`, and the coordinator-visible MCP pending-request
|
|
145
|
+
list. Subagents must stop at `waiting_for_user_permission` instead of burying a
|
|
146
|
+
Codex permission prompt in their transcript.
|
|
147
|
+
|
|
140
148
|
Codex network access may be enabled for public web, filing, disclosure, news,
|
|
141
149
|
and market-data evidence gathering. That access is read-only research support:
|
|
142
150
|
it does not authorize direct broker APIs, raw external broker MCP exposure,
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "tradingcodex"
|
|
7
|
-
version = "0.3.
|
|
7
|
+
version = "0.3.4"
|
|
8
8
|
description = "Agentic investment workflow harness for Codex-native research and service-gated execution checks."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11,<3.15"
|