Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions .agents/skills/chatnow-orienting/references/core-flows.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Core Flows

Target version: `3.0-dev`
Status: Current
Verified: 2026-07-22

These are current-state flows for the `3.0-dev` line. Re-verify affected symbols at the target commit and keep proposals in a separate section.

## HTTP request flow
Expand Down Expand Up @@ -41,12 +45,28 @@ These are current-state flows for the `3.0-dev` line. Re-verify affected symbols
**Flow:** Identity registration/login/refresh -> JWT -> Gateway or Push verification -> server-derived context -> downstream brpc metadata.

- Entry/contracts: `proto/identity/identity_service.proto`; `identity/source/identity_server.h`; `common/auth/jwt_codec.hpp`; `common/auth/jwt_store.hpp`; `gateway/source/gateway_auth.hpp`; `push/source/push_server.h`.
- Key loading: Identity, Gateway, and Push each resolve the complete JWT JSON document from exactly one of `CHATNOW_JWT_CONFIG` or `CHATNOW_JWT_CONFIG_FILE` at process startup. Identity signs and verifies; Gateway and Push verify. The codec is not hot-reloaded, so a key-set or `current_kid` change requires a controlled rollout of all affected processes.
- Stores: Identity uses MySQL for users/devices and Redis for active refresh tokens, rotation/reuse detection, and revocation state.
- Trust: Gateway validates Bearer access tokens and revocation before deriving metadata. Push verifies WS `CLIENT_AUTH` and binds claim identity to the connection. Downstream handlers use `common/auth/auth_context.hpp`; service-to-service forwarding uses `common/auth/forward_auth.hpp` where required.
- Sync/retry: Login and refresh are synchronous; refresh rotation detects reuse. Cache/store failure behavior must be inspected before changing fail-open/fail-closed semantics.
- Tests: `tests/bvt/auth_test.go`, `tests/func/identity_test.go`, `tests/func/auth_middleware_test.go`, `tests/func/security_test.go`, `tests/func/scenarios_test.go`.
- Invariants: only Identity issues/refreshes tokens; access and refresh token purposes remain distinct; downstream identity comes from verified claims and forwarded metadata, not request bodies.

## Runtime secrets

### Current

**Flow:** deployment environment or mounted secret file -> common resolver -> service startup -> dependency/auth client construction.

- `common/config/secret_resolver.hpp` owns an allowlist of logical credentials and their direct-environment/`_FILE` names. It rejects missing or conflicting sources, invalid values, symlinks, non-regular files, unexpected owners, and group/other-accessible modes.
- JWT (Identity, Gateway, Push), application MySQL (Conversation, Identity, Media, Message, Relationship), RabbitMQ (Transmite, Message, Push), SMTP (Identity), and S3 application credentials (Media) use the resolver.
- Resolution happens once at startup. Missing or unsafe input prevents the service from accepting traffic; there is no hot reload or tracked/default fallback.
- Real credential changes and production rotation require explicit human approval. Values and credential-derived fingerprints must never appear in logs or operational evidence.

### Proposed

Redis authentication, dynamic reload, automatic rotation, and additional credential classes are not implemented. They require their own scoped Issues and executable tests; do not infer them from the current resolver. See `docs/operations/runtime-secrets.md` for the exact current contract and rollback procedure.

## Media upload and download

**Flow:** Apply/init -> presigned MinIO upload -> complete -> MySQL metadata/quota -> authenticated download request -> presigned MinIO GET.
Expand Down
24 changes: 21 additions & 3 deletions .agents/skills/chatnow-orienting/references/repository-map.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Repository Map

Target version: `3.0-dev`
Status: Current
Verified: 2026-07-22

## Ownership and first reads

| Path | Ownership | First-read files |
Expand All @@ -16,13 +20,13 @@
| `presence/` | Presence aggregation, subscriptions, and typing coordination | `presence/source/presence_server.h`, `presence/source/presence_server.cc`, `proto/presence/presence_service.proto` |
| `push/` | WebSocket connections, routes, cross-instance delivery, resend, client ACK ingestion | `push/source/push_server.h`, `push/source/connection.hpp`, `push/source/push_server.cc`, `proto/push/notify.proto` |
| `odb/` | ODB entity definitions and durable relational fields | Affected entity, especially `message.hxx`, `user_timeline.hxx`, `conversation_member.hxx`, and `media_*.hxx` |
| `conf/` | Local/container flags and JSON configuration | `conf/local/`, `conf/docker/`, `conf/auth.json`, `conf/media.json` |
| `conf/` | Non-secret local/container flags and JSON configuration; tracked files are not a runtime secret source | `conf/local/`, `conf/docker/`, `conf/auth.json`, `conf/media.json` |
| `sql/` | Versioned schema migrations | `sql/V4__media.sql` and any migration matching affected ODB entities |
| `docker/` | Separate MinIO topology and initialization; not wired into the root application network | `docker/docker-compose.yml`, `docker/minio-init/entrypoint.sh` |
| `docker-compose.yml` | Application stack declaration; Media object-storage wiring is incomplete | Root `docker-compose.yml`, then affected `Dockerfile` and `conf/docker` file |
| `scripts/` | Operational support and monitoring configuration | `scripts/install_aws_sdk_linux.sh`, `scripts/prometheus/redis_alerts.yml` |
| `tests/` | Pure-Go L1-L4 framework, clients, fixtures, cleanup, and store verification | `tests/Makefile`, `tests/config.yaml`, affected `tests/bvt`, `tests/func`, `tests/perf`, `tests/pkg` |
| `docs/` | Secondary architecture/API/operations context | Affected `docs/api/*.yaml`, `docs/operations/`, then relevant architecture documents |
| `tests/` | Pure-Go L1-L4 plus Redis-focused Reliability framework, clients, fixtures, cleanup, and store verification | `tests/Makefile`, `tests/config.yaml`, affected `tests/bvt`, `tests/func`, `tests/perf`, `tests/reliability`, `tests/pkg` |
| `docs/` | Secondary architecture/API context and canonical operations guidance | `docs/operations/runtime-secrets.md`, affected `docs/api/*.yaml`, then relevant architecture documents |

## Verified ports and infrastructure endpoints

Expand Down Expand Up @@ -52,6 +56,20 @@ MySQL service configs set `mysql_port=0`, while root Compose exposes MySQL on `3

Root Compose mounts `conf/media.json` into Media, but `s3.endpoint=http://127.0.0.1:9000` addresses the Media container itself. Root Compose has no MinIO service/dependency, while the supplemental MinIO Compose project has no declared shared external network with the root project. Do not present these declarations as a working integrated Media topology or recommend their current commands as a functional Media runtime. Any repair must explicitly reconcile the network, endpoint, dependency, and `9000`/`9001` host-port conflicts, then be verified from the affected containers.

## Runtime credential ownership

Current consumers at the verified commit are:

- Identity, Gateway, and Push resolve the complete JWT JSON document from `CHATNOW_JWT_CONFIG` or `CHATNOW_JWT_CONFIG_FILE` at startup. Identity signs and verifies tokens; Gateway and Push verify them.
- Conversation, Identity, Media, Message, and Relationship resolve service-specific MySQL password inputs through `common/config/secret_resolver.hpp`.
- Transmite, Message, and Push resolve service-specific RabbitMQ password inputs through the same resolver.
- Identity resolves its SMTP password; Media resolves separate S3 access-key and secret-key inputs. Non-secret S3 settings remain in `conf/media.json`.
- Root Compose requires MySQL, RabbitMQ, and supplemental MinIO bootstrap values through deployment environment references. These are separate from least-privileged application inputs. Redis has no configured password or ACL consumer.

Tracked runtime credential literals have been removed from the scoped source, configuration, Compose, and test-runtime surfaces. Do not reintroduce values in documentation, logs, test output, Issues, or PRs. Synthetic test-only credentials and API examples require narrow scanner exemptions rather than broad path allowlists.

The canonical current inventory and injection contract are in `docs/operations/runtime-secrets.md`. Reinspect the resolver and each consumer before extending the allowlist or claiming support for a credential not named there.

## State ownership

- MySQL/ODB: durable users, relationships, conversations/members, messages/timelines, ACK high-water marks, and media metadata/quota.
Expand Down
18 changes: 15 additions & 3 deletions .agents/skills/chatnow-orienting/references/technology-stack.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Technology Stack and Entry Points

Target version: `3.0-dev`
Status: Current
Verified: 2026-07-22

Use this reference for the `3.0-dev` architecture line, then verify task-sensitive details at the resolved commit.

## Stack
Expand Down Expand Up @@ -37,10 +41,15 @@ Inspect root `CMakeLists.txt`, the affected service's `CMakeLists.txt`, and its

- Local service flags: `conf/local/*_server.conf`.
- Container service flags: `conf/docker/*_server.conf`.
- JWT keys and TTLs: `conf/auth.json`.
- Media S3, buckets, presign, and MIME policy: `conf/media.json` plus Media flags.
- JWT keys and TTLs: Identity, Gateway, and Push resolve `CHATNOW_JWT_CONFIG` or `CHATNOW_JWT_CONFIG_FILE` at process startup. The value is the complete JSON document.
- Media S3 application credentials are resolved through the common secret resolver. Buckets, endpoint, presign, and MIME policy remain in `conf/media.json` plus Media flags.
- Example Transmite flags: `conf/transmite_server.conf.example`.
- Service defaults and flag definitions: each `<service>/source/<service>_server.cc`.
- MySQL passwords for Conversation, Identity, Media, Message, and Relationship use service-specific direct-environment or `_FILE` inputs through `common/config/secret_resolver.hpp`.
- RabbitMQ passwords for Transmite, Message, and Push use the same resolver contract. Identity SMTP and Media S3 application credentials are also migrated.
- The resolver accepts exactly one allowlisted direct environment variable or `_FILE` locator, fails closed on missing/conflicting input, and validates secret-file type, owner, mode, size, and content. It reads once at startup; there is no hot reload.
- Bootstrap credentials in Compose remain deployment environment references rather than application resolver inputs. Redis has no configured password or ACL consumer.
- The canonical names, consumers, deployment rules, and limitations are maintained in `docs/operations/runtime-secrets.md`.
- Root `docker-compose.yml` declares the application stack used by CI, but it is not a complete integrated Media/MinIO topology: it starts Media without a MinIO service or dependency.
- `docker/docker-compose.yml` separately declares MinIO and its initialization sidecar on a different default Compose network. Media mounts `conf/media.json`, whose `http://127.0.0.1:9000` endpoint resolves to the Media container itself, not to that separate MinIO container.

Expand All @@ -57,7 +66,10 @@ The current test framework is entirely Go. New or restored C++ test suites are p
| L2 Functional | `tests/func`, `func` | `cd tests && make proto && make test-func` |
| L3 Scenario | `tests/func`, `func` | `cd tests && make proto && make test-scenario` |
| L4 Performance | `tests/perf`, `perf` | `cd tests && make proto && make test-perf` |
| Reliability | `tests/reliability`, `reliability` | `cd tests && make proto && make test-reliability` |

Reliability is an executable, Redis-focused layer. Its current tests exercise Redis circuit recovery and Push unacked requeue behavior through `tests/pkg/chaos/redis.go`. The Make target runs the whole layer and does not consume `TEST_RUN`; use a direct tagged `go test ... -run` command when exact selection is required. No current controller covers RabbitMQ, MySQL, arbitrary services, or general network faults, so do not describe this as a broad chaos platform.

Reliability is a distinct framework layer with the reserved `reliability` build tag. There is currently no repository path or Make target for it, so do not claim a runnable Reliability command. Shared clients, fixtures, polling, cleanup, and direct store verification live under `tests/pkg`.
The CI definition has a dedicated `reliability` job that depends on `service-artifacts`, independently of BVT. At this verification date the job exists, but the inspected PR run was skipped after an upstream failure; that is not green runtime evidence. Shared clients, fixtures, polling, cleanup, and direct store verification live under `tests/pkg`.

The CI definition is `.github/workflows/ci.yml`; verify its commands against files present at the target commit before copying them into local instructions.
10 changes: 9 additions & 1 deletion .agents/skills/chatnow-securing-changes/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ description: Use when ChatNow work touches authentication, authorization, user i

# Secure ChatNow Changes

Target version: `3.0-dev`
Status: Current
Verified: 2026-07-22

## Core principle

Treat every external value as untrusted until a named server boundary validates it. Minimize authority and exposed data, and fail securely when a high-impact decision cannot be made safely.
Expand Down Expand Up @@ -36,6 +40,9 @@ Stop when identity or ownership is ambiguous, authorization cannot be evaluated
### Identity, credentials, and logs

- Preserve server-derived identity across trusted metadata and validate it again at the receiving boundary. Never forward a client identity as authenticated context.
- Treat `docs/operations/runtime-secrets.md` as the canonical credential inventory and runtime contract. Reinspect `common/config/secret_resolver.hpp` and the executable consumer before extending it; do not create a parallel loader.
- For a migrated credential, accept exactly one of its allowlisted direct environment variable or `_FILE` companion. Reject a direct/file conflict, missing required input, an empty value, an unreadable file, a symlink, non-regular input, unexpected ownership, or permissions that grant access beyond the intended runtime identity. Do not fall back to tracked configuration or a compiled default.
- Keep deployment bootstrap credentials separate from least-privileged application credentials. Local and CI values must be unique synthetic fixtures; never copy a real credential into a repository file, command line, workflow output, test failure, or artifact.
- Never log or expose bearer tokens, authorization headers, passwords, signing keys, session secrets, cookies, presigned URLs, or real credentials. Do not create, log, or expose any credential-derived token fingerprint, including a hash, keyed HMAC, prefix, suffix, encoded value, or truncated derivative. Permit such a derivative only when an approved protocol explicitly requires it, constrain it to that protocol, and never repurpose it for diagnostics; prefer request or trace IDs.
- Minimize personal data. Prefer a trace/request ID or purpose-specific opaque correlation ID. Redact or omit user identifiers, device identifiers, message content, contact data, object names, and search text unless the Issue documents necessity, access, retention, and a safe representation.
- Write English structured logs with stable event and outcome fields. Avoid free-form concatenation of untrusted values and log injection; encode fields through the established logger.
Expand All @@ -55,7 +62,7 @@ Stop when identity or ownership is ambiguous, authorization cannot be evaluated

## Human approval boundaries

Obtain explicit human approval before using or changing real credentials, operating in production, performing irreversible migration or deletion, or intentionally changing public compatibility or settled product semantics. Approval must name the exact operation and scope. A deadline, temporary diagnostic, rollback plan, or existing access does not substitute for approval.
Obtain explicit human approval before using, rotating, revoking, or changing real credentials; operating in production; performing irreversible migration or deletion; or intentionally changing public compatibility or settled product semantics. Approval must name the exact operation and scope. A deadline, temporary diagnostic, rollback plan, or existing access does not substitute for approval.

## Test contract

Expand All @@ -66,6 +73,7 @@ Add pure-Go adversarial and regression cases for every changed boundary. Include
- SQL metacharacters and Elasticsearch field/operator/script/query-string injection, authorization-filter bypass, excessive limits, and expensive queries;
- `..`, absolute, mixed-separator, percent-encoded, NUL, symlink, bucket/prefix, and cross-user object-key traversal;
- secret and personal-data absence from logs, responses, traces, fixtures, failure output, and generated artifacts;
- direct/file secret conflicts, missing/empty input, unsafe file ownership or permissions, symlinks, and proof that tracked/default values cannot silently take over;
- dependency timeout/unavailability at a high-impact decision, proving a bounded secure failure with no partial privileged effect.

Use unique synthetic identities and credentials only. Assign cleanup ownership for users, rows, indexes/documents, objects, keys, sockets, and temporary files.
Expand Down
Loading
Loading