From 03b6ca55309e0ef6395a5dcadddc629e959e8c08 Mon Sep 17 00:00:00 2001 From: Guillaume De Saint Martin Date: Mon, 21 Sep 2026 09:25:02 +0200 Subject: [PATCH] [Agents] add more guidance on good practices --- .cursor/rules/octobot-cloud.mdc | 2 + .cursor/skills/node-journal/SKILL.md | 34 +++++++++++++++++ .cursor/skills/octobot-cloud/SKILL.md | 5 +++ AGENTS.md | 2 + CONTRIBUTING-agent.md | 34 +++++++++++++++++ octobot/AGENTS.md | 5 ++- octobot/community/node_journal/AGENTS.md | 47 ++++++++++++++++++++++++ 7 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 .cursor/skills/node-journal/SKILL.md create mode 100644 octobot/community/node_journal/AGENTS.md diff --git a/.cursor/rules/octobot-cloud.mdc b/.cursor/rules/octobot-cloud.mdc index 5c4e11f6a3..89e5df06fd 100644 --- a/.cursor/rules/octobot-cloud.mdc +++ b/.cursor/rules/octobot-cloud.mdc @@ -12,6 +12,8 @@ alwaysApply: true - **Git:** checkout `dev` (or user base) → feature branch → commit → open PR to **`dev`** unless the user specifies another target. Do not commit agent plan files (`PLAN-*.md`, `*.plan.md`, `.cursor/plans/`); use Plan mode or chat only — delete scratch plans before staging (`path.deny_agent_plans`). Do **not** edit agent docs (`**/AGENTS.md`, `.cursor/skills/**`, `.cursor/rules/**`, `.cursor/README.md`, `CONTRIBUTING-agent.md`, `tools/**/README.md`, `tools/**/ARCHITECTURE.md`) unless the task owns them; if diffs are out of scope, `git checkout origin/ -- ` before commit (`agent_docs.no_regression_vs_merge_base`). - **Node UI tests:** Vitest (`npm test`) + Python/API tests; do not add `node_web_interface/e2e/` or Playwright specs (`path.deny_node_web_playwright_e2e`). Optional live UI QA via skill **agent-seed**, not committed e2e. - **UI copy/layout:** For `packages/tentacles/Services/Interfaces/node_web_interface/` or `.../web_interface/`, read skill **end-user-ui** (entry-level trading OK, no pro jargon, minimal, no slop, no em dash in UI strings). +- **Node journal:** From outside `octobot/community/node_journal/`, **record only** (`record_*`); do not `read_events` or use journal as source of truth. Reads belong to journal export inside that package. Skill **node-journal**; [`octobot/community/node_journal/AGENTS.md`](octobot/community/node_journal/AGENTS.md). +- **Python conventions:** Shared literals in package-top `constants.py` / `enums.py` (e.g. `octobot/constants.py`); top-level `import module as alias`; no lazy imports unless exceptional; public API via `__init__.py` re-exports (`from` imports only in `__init__.py`). Full detail: [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — **Python conventions (agents)**. - Before handoff: `python -m tools.extended_linter --base origin/dev` (use `origin/` matching the PR target). - No `pip install` / `npm install` to fix imports. No edits under `user/` or secret/env files. - Cross-package or tentacles work: read root `AGENTS.md` and colocated `AGENTS.md` for every area you touch (`octobot/`, `packages//`, `packages/tentacles/`). diff --git a/.cursor/skills/node-journal/SKILL.md b/.cursor/skills/node-journal/SKILL.md new file mode 100644 index 0000000000..67473cd48f --- /dev/null +++ b/.cursor/skills/node-journal/SKILL.md @@ -0,0 +1,34 @@ +--- +name: node-journal +description: >- + Node journal (octobot.community.node_journal): record-only from outside the + package; reads only for export inside node_journal; not a source of truth. + Apply when editing node_journal or adding/changing record_* calls elsewhere. +paths: + - octobot/community/node_journal/** +--- + +# Node journal + +Full rules: [`octobot/community/node_journal/AGENTS.md`](../../../octobot/community/node_journal/AGENTS.md). + +## Purpose + +Append-only **event log** for diagnostics, journey analytics, and **export/sharing** (upload envelope). Not authoritative application state. + +## Integrators (outside `node_journal/`) + +- Import `octobot.community.node_journal` and call Tier-1 **`record_*`** / `record` only. +- Do **not** call `read_events`, read journal files on disk, or branch product logic on journal contents. +- Do **not** store data in journal payloads to reuse later for non-journal features. Use config, DB, sync collections, or domain stores as source of truth. + +## Inside `octobot/community/node_journal/` + +- **`read_events`**, `build_journey_summary`, and `build_upload_envelope` belong to the **export pipeline** (plus unit tests). +- Event and wire literals: extend [`events.py`](../../../octobot/community/node_journal/events.py), [`constants.py`](../../../octobot/community/node_journal/constants.py), [`enums.py`](../../../octobot/community/node_journal/enums.py); do not inline strings in recording code. +- Respect import tiers in package [`__init__.py`](../../../octobot/community/node_journal/__init__.py); feature code must not reach into `store` / `state` except via the public API. + +## Related + +- Core app boundaries: [`octobot/AGENTS.md`](../../../octobot/AGENTS.md) +- Python conventions (shared literals, imports): [CONTRIBUTING-agent.md](../../../CONTRIBUTING-agent.md) — **Python conventions (agents)** diff --git a/.cursor/skills/octobot-cloud/SKILL.md b/.cursor/skills/octobot-cloud/SKILL.md index 35760294b7..6fcc3728b1 100644 --- a/.cursor/skills/octobot-cloud/SKILL.md +++ b/.cursor/skills/octobot-cloud/SKILL.md @@ -33,6 +33,11 @@ Multi-step **roadmap** plans (title or description contains `roadmap`): author w - Installed tentacles output: repo-root `tentacles/` (generated — never edit). - Tentacles sources: `packages/tentacles/`. +## Coding conventions + +- **Python (imports, literals, public API):** [CONTRIBUTING-agent.md](../../CONTRIBUTING-agent.md) — **Python conventions (agents)**. +- **Node journal:** skill **node-journal** (`.cursor/skills/node-journal/SKILL.md`); colocated [`octobot/community/node_journal/AGENTS.md`](../../octobot/community/node_journal/AGENTS.md). Integrators record only; not a source of truth. + ## Policy and verify - Machine rules: `tools/extended_linter/config/policy.yaml` (extend via `tools/extended_linter/ARCHITECTURE.md`) diff --git a/AGENTS.md b/AGENTS.md index 5546ec3bb3..c95b1c7528 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,6 +30,8 @@ Colocated **`AGENTS.md`** files describe package boundaries (owns, deps, tests). | Core app / CLI / config | [`octobot/AGENTS.md`](octobot/AGENTS.md) | | Tentacles sources vs install | [`packages/tentacles/AGENTS.md`](packages/tentacles/AGENTS.md) | | Node UI or classic web UI (copy, layout, errors) | [`packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/node_web_interface/AGENTS.md), [`packages/tentacles/Services/Interfaces/web_interface/AGENTS.md`](packages/tentacles/Services/Interfaces/web_interface/AGENTS.md), skill **end-user-ui** (`.cursor/skills/end-user-ui/SKILL.md`) | +| Node journal (record / export) | [`octobot/community/node_journal/AGENTS.md`](octobot/community/node_journal/AGENTS.md), skill **node-journal** (`.cursor/skills/node-journal/SKILL.md`) | +| Python style (imports, literals, `__init__.py` API) | [CONTRIBUTING-agent.md](CONTRIBUTING-agent.md) — **Python conventions (agents)** | | Cross-package or tentacles | This file + every involved colocated `AGENTS.md` | | Node UI demo / agent-seed QA | [`tools/agent_seed/README.md`](tools/agent_seed/README.md) + skill **agent-seed** (`.cursor/skills/agent-seed/SKILL.md`) | diff --git a/CONTRIBUTING-agent.md b/CONTRIBUTING-agent.md index 8fddb3e516..3c9476077b 100644 --- a/CONTRIBUTING-agent.md +++ b/CONTRIBUTING-agent.md @@ -68,6 +68,40 @@ One paragraph: what this package does in OctoBot. - YYYY-MM-DD ``` +## Node journal + +The node journal (`octobot.community.node_journal`) is an append-only event log for diagnostics, journey analytics, and **export/sharing**. It is **not** a source of truth. + +- **Outside `octobot/community/node_journal/`:** call Tier-1 **`record_*`** / `record` only. Do not call `read_events`, read journal files on disk, or branch product logic on journal contents. +- **Inside the package:** `read_events`, `build_journey_summary`, and `build_upload_envelope` are for the **export pipeline** (plus unit tests). +- Do not store data in journal payloads to reuse later for non-journal features; use config, DB, sync collections, or domain stores instead. +- Details: [`octobot/community/node_journal/AGENTS.md`](octobot/community/node_journal/AGENTS.md) and skill **node-journal** (`.cursor/skills/node-journal/SKILL.md`). + +## Python conventions (agents) + +Authoritative rules for Python in `octobot/` and `packages/`. Cloud agents: also summarized in `.cursor/rules/octobot-cloud.mdc`. + +### Shared literals (magic strings) + +- Put cross-module identifiers in the **owning package** at **package top level** when only a few literals are needed: e.g. [`octobot/constants.py`](octobot/constants.py), [`octobot/enums.py`](octobot/enums.py), or `packages//octobot_/constants.py` and `enums.py`. +- TypeScript: `constants.ts` / `wireConstants.ts` where applicable; see [`docs/content/client-sdk/wire-contract.md`](docs/content/client-sdk/wire-contract.md) for cross-language wire literals. +- Callers use `import module as alias` and `alias.NAME`; do not duplicate the same string in multiple files. +- **OK inline:** log/debug text; truly local one-off values never compared or reused elsewhere. +- **Submodule `constants.py` / `enums.py`:** only when a sub-area owns a **large** dedicated literal surface (exemplar: [`octobot/community/node_journal/constants.py`](octobot/community/node_journal/constants.py), [`enums.py`](octobot/community/node_journal/enums.py)). Do not add deep per-folder constant files for a handful of strings. + +### Imports + +- Prefer imports at **module top level**. +- Use `import xxx` or `import xxx as yy`; access via `xxx.name` or `yy.name`. +- Avoid `from xxx import yy` in normal module code; avoid lazy (function-scoped) imports unless breaking a documented import cycle or loading an optional heavy dependency on a rare path. +- **`from xxx import yyy` is allowed only in `__init__.py`** when re-exporting the public surface (see below). + +### Package `__init__.py` as public bridge + +- Re-export the **public surface** from each package/subpackage `__init__.py` so callers use one stable import (e.g. `import octobot_trading.personal_data as personal_data`) instead of deep internal paths. +- Example: [`packages/trading/octobot_trading/personal_data/__init__.py`](packages/trading/octobot_trading/personal_data/__init__.py). +- When adding a new public symbol, export it from the appropriate `__init__.py`. + ## Formatting Ruff/Biome configs are present; mass format and CI enforce land in later phases. Do not run repo-wide reformat in routine agent PRs unless requested. diff --git a/octobot/AGENTS.md b/octobot/AGENTS.md index ec7a81e898..d6c81db92f 100644 --- a/octobot/AGENTS.md +++ b/octobot/AGENTS.md @@ -24,6 +24,9 @@ Top-level OctoBot app: CLI entry, configuration, community features, orchestrati - Edit repo-root `tentacles/` (install output) - Put secrets or `user/` data in tree - Duplicate logic that belongs in `packages/*` +- Use **node journal** for reads or control flow outside export: record-only via `octobot.community.node_journal` from the rest of the app (see [`community/node_journal/AGENTS.md`](community/node_journal/AGENTS.md), skill **node-journal**) +- Duplicate shared wire/config/event strings; use package-top [`constants.py`](constants.py) / [`enums.py`](enums.py) (or the owning package’s equivalents) +- Use `from xxx import yyy` or lazy imports in normal modules (only `__init__.py` re-exports; see [CONTRIBUTING-agent.md](../CONTRIBUTING-agent.md) — **Python conventions (agents)**) ## Tests @@ -37,4 +40,4 @@ Top-level OctoBot app: CLI entry, configuration, community features, orchestrati ## Last reviewed -- 2026-03-25 +- 2026-09-21 diff --git a/octobot/community/node_journal/AGENTS.md b/octobot/community/node_journal/AGENTS.md new file mode 100644 index 0000000000..e374080809 --- /dev/null +++ b/octobot/community/node_journal/AGENTS.md @@ -0,0 +1,47 @@ +# Agents: node_journal + +## Role + +Append-only **node journal**: record lifecycle and user-journey events for diagnostics, analytics, and **export/sharing** (e.g. upload envelope). Tier-1 API: `octobot.community.node_journal` (see [`__init__.py`](__init__.py) import tiers). + +## Owns + +- `octobot/community/node_journal/` (recording, store, state, journey export) + +## Public surface (integrators) + +- **Write:** `record`, `record_*` helpers exported from `octobot.community.node_journal` +- **Read (export only):** `read_events`, `build_journey_summary`, `build_upload_envelope` for journal export pipeline inside this package (and tests) + +## External integrators (`packages/sync`, wallet, node, tentacles, etc.) + +- **Record only.** Do not call `read_events`, read journal files on disk, or use journal contents for control flow. +- Do not treat journal or [`state.py`](state.py) persistence as source of truth for app behavior. + +## Not a source of truth + +- Do not store data in journal payloads to reuse later for non-journal features. +- Authoritative state lives in config, databases, sync collections, and domain modules, not the journal. + +## Literals + +- Journal-specific events and wire keys: [`events.py`](events.py), [`constants.py`](constants.py), [`enums.py`](enums.py) (large dedicated set; submodule files are the exception to package-top-level constants). +- Extend those modules; do not inline strings in recording code. + +## Layers + +- Follow layer rules in package docstring: `journal` / `store` / `state` must not import from `recording/` or `lifecycle` in forbidden directions; feature code uses the public API only. + +## Tests + +- **cwd:** repo root +- **Example:** `pytest tests/unit_tests/community/node_journal` + +## Related + +- Skill **node-journal** (`.cursor/skills/node-journal/SKILL.md`) +- [`octobot/AGENTS.md`](../../AGENTS.md) + +## Last reviewed + +- 2026-09-21