docs: align config and github workflow (#314)
* docs: align config and positioning copy * docs: remove internal branch workflow residue * docs: record github sync guard * chore: retrigger commit lint * docs: leave readme files unchanged * docs: remove public positioning comparison
This commit is contained in:
parent
b7d15f7252
commit
0341f1230f
|
|
@ -26,8 +26,8 @@ standard. The format is enforced by `gitlint` in the `commit-msg` hook.
|
|||
```
|
||||
|
||||
5. Never use `--no-verify`. If pre-commit hooks fail, fix the cause and re-commit.
|
||||
6. Do not commit secrets, generated artifacts, or work-in-progress to a
|
||||
protected branch (`main` / `dev` / `master`).
|
||||
6. Do not commit secrets, generated artifacts, or work-in-progress directly to
|
||||
the protected `main` branch.
|
||||
|
||||
## Types
|
||||
|
||||
|
|
|
|||
|
|
@ -1,43 +1,44 @@
|
|||
---
|
||||
name: new-branch
|
||||
description: Create a branch following the project's GitFlow Lite model
|
||||
description: Create a GitHub branch from main with the project naming convention
|
||||
---
|
||||
|
||||
# /new-branch
|
||||
|
||||
Cut a new branch under the GitFlow Lite model.
|
||||
Cut a new branch for the GitHub repository.
|
||||
|
||||
## Branch model
|
||||
|
||||
```
|
||||
master = released / stable (tagged on release; protected)
|
||||
dev = integration branch (protected)
|
||||
feat/* = cut from dev → PR → merge into dev
|
||||
fix/* = cut from dev → PR → merge into dev
|
||||
hotfix/* = cut from master → merge into master AND synced into dev (double merge)
|
||||
release = dev → master + tag on master (no separate release branch)
|
||||
main = default and protected branch
|
||||
feat/* = feature work
|
||||
fix/* = bug fixes
|
||||
docs/* = documentation-only changes
|
||||
ci/* = CI, build, and developer-experience changes
|
||||
chore/* = repository maintenance
|
||||
refactor/* = behavior-preserving code structure changes
|
||||
```
|
||||
|
||||
## Steps
|
||||
|
||||
1. Ask (or infer) the change type: `feat`, `fix`, or `hotfix`.
|
||||
2. Pick the parent:
|
||||
- `feat/*`, `fix/*` → branch from **`dev`**.
|
||||
- `hotfix/*` → branch from **`master`**.
|
||||
3. Update the parent first:
|
||||
1. Ask (or infer) the change type: `feat`, `fix`, `docs`, `ci`, `chore`, or
|
||||
`refactor`.
|
||||
2. Update `main` first:
|
||||
```bash
|
||||
git checkout <parent>
|
||||
git checkout main
|
||||
git pull --ff-only
|
||||
```
|
||||
4. Create the branch with a kebab-case slug:
|
||||
3. Create the branch with a kebab-case slug:
|
||||
```bash
|
||||
git checkout -b feat/<short-slug>
|
||||
git checkout -b <type>/<short-slug>
|
||||
```
|
||||
5. For a `hotfix`, remember it must later merge into **both** `master` and `dev`.
|
||||
4. Keep the branch scoped to one purpose and open a pull request back to
|
||||
`main`.
|
||||
|
||||
## Naming
|
||||
|
||||
- `feat/add-agentic-rerank`, `fix/empty-profile-crash`, `hotfix/lancedb-conn-leak`.
|
||||
- `feat/add-agentic-rerank`, `fix/empty-profile-crash`,
|
||||
`docs/quickstart-config`, `ci/check-github-docs`.
|
||||
- Lowercase, hyphen-separated, no spaces, concise.
|
||||
|
||||
Never commit directly to `master` or `dev` — always via a branch + PR.
|
||||
Never commit directly to `main` — always use a branch and pull request.
|
||||
|
|
|
|||
|
|
@ -10,8 +10,9 @@ Open a pull request on GitHub using the `gh` CLI and the repo's PR template.
|
|||
## Steps
|
||||
|
||||
1. Confirm the branch and target:
|
||||
- `feat/*`, `fix/*` → base **`dev`**.
|
||||
- `hotfix/*` → base **`master`** (then a follow-up PR/sync into `dev`).
|
||||
- Base branch is **`main`**.
|
||||
- Head branch should be a scoped branch such as `feat/*`, `fix/*`,
|
||||
`docs/*`, `ci/*`, `chore/*`, or `refactor/*`.
|
||||
2. Ensure local checks pass first:
|
||||
```bash
|
||||
make ci
|
||||
|
|
@ -24,7 +25,7 @@ Open a pull request on GitHub using the `gh` CLI and the repo's PR template.
|
|||
4. Create the PR, filling the template
|
||||
([.github/PULL_REQUEST_TEMPLATE.md](../../../.github/PULL_REQUEST_TEMPLATE.md)):
|
||||
```bash
|
||||
gh pr create --base dev --fill-first
|
||||
gh pr create --base main --fill-first
|
||||
```
|
||||
Then edit the body to complete each section:
|
||||
- **Summary** — what changed and why.
|
||||
|
|
@ -38,4 +39,5 @@ Open a pull request on GitHub using the `gh` CLI and the repo's PR template.
|
|||
|
||||
- Keep the PR scoped to one area. Split unrelated changes.
|
||||
- If `make ci` was not fully run, say so in Verification rather than implying it passed.
|
||||
- A `hotfix` is not done until it has landed on **both** `master` and `dev`.
|
||||
- Never retarget a community PR away from `main` unless a maintainer explicitly
|
||||
asks for it.
|
||||
|
|
|
|||
|
|
@ -7,7 +7,11 @@ on:
|
|||
- ".github/ISSUE_TEMPLATE/**"
|
||||
- ".github/PULL_REQUEST_TEMPLATE.md"
|
||||
- ".github/workflows/docs.yml"
|
||||
- ".claude/skills/**/*.md"
|
||||
- "CLAUDE.md"
|
||||
- "CONTRIBUTING.md"
|
||||
- "scripts/check_docs.py"
|
||||
- "scripts/check_github_contributor_docs.py"
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
|
|
@ -15,7 +19,11 @@ on:
|
|||
- ".github/ISSUE_TEMPLATE/**"
|
||||
- ".github/PULL_REQUEST_TEMPLATE.md"
|
||||
- ".github/workflows/docs.yml"
|
||||
- ".claude/skills/**/*.md"
|
||||
- "CLAUDE.md"
|
||||
- "CONTRIBUTING.md"
|
||||
- "scripts/check_docs.py"
|
||||
- "scripts/check_github_contributor_docs.py"
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
|
|
|||
|
|
@ -32,9 +32,9 @@ BibTeX citation information will be added here once the paper is published.
|
|||
To cite the software itself:
|
||||
|
||||
```
|
||||
EverOS: md-first memory extraction framework for AI agents
|
||||
Version: 0.1.0
|
||||
URL: https://github.com/EverMind-AI/everos
|
||||
EverOS: local-first memory runtime for AI agents
|
||||
Version: 1.1.0
|
||||
URL: https://github.com/EverMind-AI/EverOS
|
||||
License: Apache 2.0
|
||||
```
|
||||
|
||||
|
|
|
|||
14
CLAUDE.md
14
CLAUDE.md
|
|
@ -47,9 +47,19 @@ Contributor engineering reference — build, test, CI gates, branch & commit con
|
|||
|
||||
## Branch strategy
|
||||
|
||||
`master` = released stable (hidden); `dev` = integration; `feat/* fix/*` → dev; `hotfix/*` → master + dev (sync).
|
||||
`main` is the default and protected branch. Create scoped branches from
|
||||
`main` (`feat/*`, `fix/*`, `docs/*`, `ci/*`, `chore/*`, `refactor/*`) and open
|
||||
pull requests back to `main` after the required checks pass.
|
||||
|
||||
See [.claude/skills/new-branch/SKILL.md](.claude/skills/new-branch/SKILL.md) for the full GitFlow Lite rationale.
|
||||
See [.claude/skills/new-branch/SKILL.md](.claude/skills/new-branch/SKILL.md)
|
||||
for the full branch workflow.
|
||||
|
||||
## GitHub sync guard
|
||||
|
||||
When refreshing this repository from an internal source archive, preserve
|
||||
GitHub-only contributor and automation files. Do not overwrite `CLAUDE.md`,
|
||||
`.claude/skills/*`, `CONTRIBUTING.md`, or `.github/*` workflow/template files
|
||||
without checking [docs/github-sync.md](docs/github-sync.md).
|
||||
|
||||
## Storage three-piece set
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ internally.
|
|||
git clone https://github.com/EverMind-AI/EverOS.git
|
||||
cd EverOS
|
||||
make install # deps + pre-commit hooks (one-stop dev setup)
|
||||
everos init # write ./.env, then fill in the API key slots
|
||||
everos init # write ~/.everos/everos.toml + ome.toml
|
||||
make ci # verify: lint + unit + integration + package
|
||||
```
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ Full conventions: [.claude/rules/testing.md](.claude/rules/testing.md).
|
|||
|
||||
- `/new-branch` — create branch with proper naming
|
||||
- `/commit` — generate a Conventional Commits message
|
||||
- `/pr` — internal merge request with correct target branch
|
||||
- `/pr` — open a GitHub pull request with the correct target branch
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
10
Makefile
10
Makefile
|
|
@ -1,4 +1,4 @@
|
|||
.PHONY: help install install-deps lint docs-check check-commits check-pr-title check-assets check-deprecated-names check-cjk check-datetime openapi check-openapi format test integration package cov ci clean
|
||||
.PHONY: help install install-deps lint docs-check check-commits check-pr-title check-assets check-deprecated-names check-github-docs check-cjk check-datetime openapi check-openapi format test integration package cov ci clean
|
||||
|
||||
help:
|
||||
@echo "Targets:"
|
||||
|
|
@ -10,6 +10,7 @@ help:
|
|||
@echo " check-pr-title Validate PR title uses Conventional Commit format"
|
||||
@echo " check-assets Block committed images, videos, and asset/media directories"
|
||||
@echo " check-deprecated-names Block deprecated product names"
|
||||
@echo " check-github-docs Block legacy/internal branch-model residue in contributor docs"
|
||||
@echo " check-cjk Scan for CJK outside the language-policy allowlist (advisory)"
|
||||
@echo " check-datetime Scan for code that bypasses component/utils/datetime (HARD gate, run via lint)"
|
||||
@echo " openapi Regenerate docs/openapi.json from the FastAPI app"
|
||||
|
|
@ -39,11 +40,13 @@ lint:
|
|||
uv run lint-imports
|
||||
uv run python scripts/check_repo_assets.py
|
||||
uv run python scripts/check_deprecated_names.py
|
||||
uv run python scripts/check_github_contributor_docs.py
|
||||
uv run python scripts/check_datetime_discipline.py
|
||||
uv run python scripts/dump_openapi.py --check
|
||||
|
||||
docs-check:
|
||||
python3 scripts/check_docs.py
|
||||
python3 scripts/check_github_contributor_docs.py
|
||||
ruby -e 'require "yaml"; Dir[".github/ISSUE_TEMPLATE/*.yml"].sort.each { |p| YAML.load_file(p); puts "YAML ok: #{p}" }'
|
||||
|
||||
check-commits:
|
||||
|
|
@ -61,6 +64,11 @@ check-assets:
|
|||
check-deprecated-names:
|
||||
uv run python scripts/check_deprecated_names.py
|
||||
|
||||
# GitHub contributor-doc gate. Public contribution guidance must target the
|
||||
# GitHub `main` workflow, not an internal branch model.
|
||||
check-github-docs:
|
||||
uv run python scripts/check_github_contributor_docs.py
|
||||
|
||||
# Advisory CJK scan (see .claude/rules/language-policy.md). Deliberately NOT
|
||||
# wired into `lint` / `ci`: the policy is enforced by review and the rules
|
||||
# doc, not a hard gate. Run on demand when touching potentially-CJK files.
|
||||
|
|
|
|||
|
|
@ -10,15 +10,19 @@ front of your agent.
|
|||
## Prerequisites
|
||||
|
||||
- **Python 3.12+**
|
||||
- **An OpenRouter API key** — covers the chat LLM (memory extraction)
|
||||
*and* the multimodal LLM (parsing image / pdf / audio content items)
|
||||
with a single key.
|
||||
- **A DeepInfra API key** — for the embedding + rerank models that
|
||||
OpenRouter doesn't ship.
|
||||
- **An LLM provider key and endpoint** — for memory extraction. OpenRouter,
|
||||
OpenAI, and other OpenAI-compatible providers work when you set
|
||||
`base_url`.
|
||||
- **A multimodal provider key and endpoint** — needed only when parsing
|
||||
image / pdf / audio content items.
|
||||
- **Embedding and rerank provider keys and endpoints** — for search. DeepInfra
|
||||
works for the embedding + rerank path; vLLM and DashScope are also supported
|
||||
for rerank.
|
||||
|
||||
Two keys total. Any OpenAI-compatible endpoint plugs in via the
|
||||
matching `*__BASE_URL` env var if you'd rather use OpenAI directly,
|
||||
self-host vLLM, route to Ollama, etc.
|
||||
Many deployments use two distinct keys by reusing one LLM key for `[llm]` and
|
||||
`[multimodal]`, and one DeepInfra key for `[embedding]` and `[rerank]`. Any
|
||||
setting can live in TOML or be overridden by the matching `EVEROS_*`
|
||||
environment variable.
|
||||
|
||||
## 1. Install
|
||||
|
||||
|
|
@ -29,15 +33,15 @@ pip install everos
|
|||
|
||||
## 2. Configure
|
||||
|
||||
Generate the starter config and drop in your two keys:
|
||||
Generate the starter config and fill in provider credentials:
|
||||
|
||||
```bash
|
||||
everos init # writes ~/.everos/everos.toml + ome.toml (use --root to relocate)
|
||||
# Edit ~/.everos/everos.toml and fill four api_key slots (only two distinct keys needed):
|
||||
# [llm] api_key (OpenRouter — chat LLM)
|
||||
# [multimodal] api_key (OpenRouter — same key works)
|
||||
# [embedding] api_key (DeepInfra)
|
||||
# [rerank] api_key (DeepInfra — same key works)
|
||||
# Edit ~/.everos/everos.toml and fill the provider fields:
|
||||
# [llm] api_key + base_url (chat LLM)
|
||||
# [multimodal] api_key + base_url (optional parser LLM)
|
||||
# [embedding] model + api_key + base_url
|
||||
# [rerank] model + api_key + base_url (provider can be inferred or set)
|
||||
```
|
||||
|
||||
`everos init` generates two files: `everos.toml` (provider settings)
|
||||
|
|
@ -48,9 +52,9 @@ after editing: `chmod 600 ~/.everos/everos.toml`.
|
|||
The shipped template sets model defaults for `[llm]` (`gpt-4.1-mini`) and
|
||||
`[multimodal]` (`google/gemini-3-flash-preview`); `[embedding]` and
|
||||
`[rerank]` ship no model default — set `model` + `base_url` for those two
|
||||
sections yourself (e.g. DeepInfra's `Qwen/Qwen3-Embedding-4B` /
|
||||
`Qwen/Qwen3-Reranker-4B`). To use a different OpenAI-compatible endpoint
|
||||
for any provider, set the matching `base_url` field.
|
||||
sections yourself (for example DeepInfra's `Qwen/Qwen3-Embedding-4B` /
|
||||
`Qwen/Qwen3-Reranker-4B`). `[llm]` and `[multimodal]` ship model defaults,
|
||||
but still need `api_key` and `base_url` before those capabilities are used.
|
||||
|
||||
> **Where config lives** — `everos init` writes into the memory root
|
||||
> (`~/.everos` by default; relocate with `everos init --root <path>` and
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## Supported Versions
|
||||
|
||||
EverOS is released and at v1.0.0 (stable). Security fixes are applied to the
|
||||
EverOS is released and in the v1.x stable line. Security fixes are applied to the
|
||||
latest release line only.
|
||||
|
||||
| Version | Supported |
|
||||
|
|
@ -39,8 +39,9 @@ following in mind:
|
|||
is loopback-only. Only set the bind to `0.0.0.0` (or any routable interface)
|
||||
after you have placed your own gateway / auth layer in front;
|
||||
`everos server start` will log a warning when you bind to `0.0.0.0`.
|
||||
- Secrets (LLM / embedding API keys) live in your local `.env`; protect that
|
||||
file as you would any credential. EverOS never transmits them anywhere except
|
||||
the providers you configure.
|
||||
- Secrets (LLM / embedding / rerank API keys) normally live in your local
|
||||
`<root>/everos.toml`, or in `EVEROS_*` environment variables for container
|
||||
deployments. Protect those values as you would any credential. EverOS never
|
||||
transmits them anywhere except the providers you configure.
|
||||
- Memory content is stored as plaintext `.md` files; apply OS-level file
|
||||
permissions or disk encryption if your data is sensitive.
|
||||
|
|
|
|||
|
|
@ -105,7 +105,7 @@ everos init --root /data/everos
|
|||
|---|---|---|---|---|
|
||||
| `model` | string | `"gpt-4.1-mini"` | No | LLM model identifier. |
|
||||
| `api_key` | string | — | **Yes** | API key for the LLM provider. |
|
||||
| `base_url` | string | — | No | Custom endpoint URL (OpenAI-compatible). |
|
||||
| `base_url` | string | — | **Yes** | Endpoint URL (OpenAI-compatible). |
|
||||
|
||||
### `[multimodal]`
|
||||
|
||||
|
|
@ -113,7 +113,7 @@ everos init --root /data/everos
|
|||
|---|---|---|---|---|
|
||||
| `model` | string | `"google/gemini-3-flash-preview"` | No | Multimodal parsing model. |
|
||||
| `api_key` | string | — | **Yes** | API key. |
|
||||
| `base_url` | string | — | No | Custom endpoint URL. |
|
||||
| `base_url` | string | — | **Yes** | Endpoint URL. |
|
||||
| `max_concurrency` | int | `4` | No | Max parallel parsing requests. |
|
||||
| `file_uri_allow_dirs` | list[string] | `[]` | No | Allowlisted base dirs for `file://` URIs. Empty = allow any readable file. |
|
||||
| `file_uri_max_bytes` | int | `52428800` | No | Max size (bytes) of a `file://` asset; larger files are rejected. |
|
||||
|
|
@ -134,7 +134,7 @@ everos init --root /data/everos
|
|||
|
||||
| Field | Type | Default | Required | Description |
|
||||
|---|---|---|---|---|
|
||||
| `provider` | string | `"deepinfra"` | No | Rerank provider: `deepinfra` or `vllm`. |
|
||||
| `provider` | string | inferred | No | Rerank provider: `deepinfra`, `vllm`, or `dashscope`. |
|
||||
| `model` | string | — | **Yes** | Reranker model identifier. |
|
||||
| `api_key` | string | — | **Yes** | API key. |
|
||||
| `base_url` | string | — | **Yes** | Rerank endpoint URL. |
|
||||
|
|
@ -210,9 +210,13 @@ variables directly:
|
|||
ENV EVEROS_ROOT=/data/everos
|
||||
ENV EVEROS_LLM__API_KEY=sk-...
|
||||
ENV EVEROS_LLM__MODEL=gpt-4o
|
||||
ENV EVEROS_LLM__BASE_URL=https://api.openai.com/v1
|
||||
ENV EVEROS_EMBEDDING__MODEL=text-embedding-3-large
|
||||
ENV EVEROS_EMBEDDING__API_KEY=sk-...
|
||||
ENV EVEROS_EMBEDDING__BASE_URL=https://api.openai.com/v1
|
||||
ENV EVEROS_RERANK__MODEL=Qwen/Qwen3-Reranker-4B
|
||||
ENV EVEROS_RERANK__API_KEY=...
|
||||
ENV EVEROS_RERANK__BASE_URL=https://api.deepinfra.com/v1/inference
|
||||
ENV EVEROS_API__HOST=0.0.0.0
|
||||
ENV EVEROS_API__PORT=8000
|
||||
```
|
||||
|
|
|
|||
|
|
@ -0,0 +1,77 @@
|
|||
# GitHub Sync Guard
|
||||
|
||||
This page records the GitHub-only files that must be preserved when refreshing
|
||||
this public repository from the internal GitLab source/export.
|
||||
|
||||
## Rule
|
||||
|
||||
When a GitLab export, archive, rsync, or scripted copy is used to refresh the
|
||||
GitHub repository, do **not** blindly overwrite GitHub-only contributor,
|
||||
automation, and public-facing workflow files.
|
||||
|
||||
These files describe the public GitHub workflow: protected `main`, scoped
|
||||
branches, GitHub pull requests, GitHub Actions, and community contribution
|
||||
rules. Internal workflow text can mislead contributors and AI coding tools if
|
||||
it is copied into GitHub.
|
||||
|
||||
## Preserve These GitHub Files
|
||||
|
||||
Keep the GitHub versions of these files unless a maintainer deliberately updates
|
||||
them for the public GitHub workflow:
|
||||
|
||||
- `CLAUDE.md`
|
||||
- `CONTRIBUTING.md`
|
||||
- `.github/PULL_REQUEST_TEMPLATE.md`
|
||||
- `.github/BRANCH_PROTECTION.md`
|
||||
- `.github/workflows/ci.yml`
|
||||
- `.github/workflows/docs.yml`
|
||||
- `.github/workflows/commits.yml`
|
||||
- `.github/ISSUE_TEMPLATE/**`
|
||||
- `.claude/skills/commit/SKILL.md`
|
||||
- `.claude/skills/new-branch/SKILL.md`
|
||||
- `.claude/skills/pr/SKILL.md`
|
||||
- `scripts/check_github_contributor_docs.py`
|
||||
- `tests/unit/test_scripts/test_check_github_contributor_docs.py`
|
||||
|
||||
## Safe Sync Pattern
|
||||
|
||||
Prefer an explicit exclude list in the sync job rather than manual cleanup after
|
||||
the overwrite. Example shape:
|
||||
|
||||
```bash
|
||||
rsync -a --delete \
|
||||
--exclude 'CLAUDE.md' \
|
||||
--exclude 'CONTRIBUTING.md' \
|
||||
--exclude '.github/PULL_REQUEST_TEMPLATE.md' \
|
||||
--exclude '.github/BRANCH_PROTECTION.md' \
|
||||
--exclude '.github/workflows/ci.yml' \
|
||||
--exclude '.github/workflows/docs.yml' \
|
||||
--exclude '.github/workflows/commits.yml' \
|
||||
--exclude '.github/ISSUE_TEMPLATE/' \
|
||||
--exclude '.claude/skills/commit/SKILL.md' \
|
||||
--exclude '.claude/skills/new-branch/SKILL.md' \
|
||||
--exclude '.claude/skills/pr/SKILL.md' \
|
||||
--exclude 'scripts/check_github_contributor_docs.py' \
|
||||
--exclude 'tests/unit/test_scripts/test_check_github_contributor_docs.py' \
|
||||
<gitlab-export>/ <github-checkout>/
|
||||
```
|
||||
|
||||
After any sync, run:
|
||||
|
||||
```bash
|
||||
make docs-check
|
||||
make lint
|
||||
```
|
||||
|
||||
The `check_github_contributor_docs.py` gate catches the known failure mode:
|
||||
public contributor docs drifting back to an internal branch/review model.
|
||||
|
||||
## Review Checklist
|
||||
|
||||
Before opening a sync PR:
|
||||
|
||||
- Confirm `CLAUDE.md` says branches are created from `main`.
|
||||
- Confirm `.claude/skills/pr/SKILL.md` creates PRs with `--base main`.
|
||||
- Confirm `CONTRIBUTING.md` says GitHub pull request, not internal review
|
||||
terminology.
|
||||
- Confirm `make docs-check` and `make lint` both pass.
|
||||
|
|
@ -50,6 +50,7 @@ specific thing (drain a queue, recover from a stuck row, etc.).
|
|||
| Doc | Purpose |
|
||||
|---|---|
|
||||
| [cascade_runbook.md](cascade_runbook.md) | Cascade subsystem ops — drain queue, recover stuck rows |
|
||||
| [github-sync.md](github-sync.md) | Guardrails for refreshing GitHub from internal exports without overwriting GitHub-only workflow files |
|
||||
| [locomo_benchmark.md](locomo_benchmark.md) | LoCoMo benchmark — run and evaluate |
|
||||
|
||||
## Engineering
|
||||
|
|
|
|||
|
|
@ -147,7 +147,7 @@ Ruminer brings persistent memory to a browser agent so it can carry personal con
|
|||
|
||||
#### EverMem Sync with EverOS
|
||||
|
||||
One command to connect any AI coding CLI to EverMemOS long-term memory.
|
||||
One command to connect any AI coding CLI to EverOS long-term memory.
|
||||
|
||||
[Code](https://github.com/nanxingw/EverMem)
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,133 @@
|
|||
"""Block legacy/internal branch-model residue in contributor guidance docs."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
from collections.abc import Iterable
|
||||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
MONITORED_FILES = (
|
||||
Path("CLAUDE.md"),
|
||||
Path("CONTRIBUTING.md"),
|
||||
Path("docs/engineering.md"),
|
||||
Path(".github/PULL_REQUEST_TEMPLATE.md"),
|
||||
Path(".claude/skills/commit/SKILL.md"),
|
||||
Path(".claude/skills/new-branch/SKILL.md"),
|
||||
Path(".claude/skills/pr/SKILL.md"),
|
||||
)
|
||||
|
||||
BRANCH_WORKFLOW_FILES = frozenset(
|
||||
{
|
||||
Path("CLAUDE.md"),
|
||||
Path(".claude/skills/commit/SKILL.md"),
|
||||
Path(".claude/skills/new-branch/SKILL.md"),
|
||||
Path(".claude/skills/pr/SKILL.md"),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Rule:
|
||||
label: str
|
||||
pattern: re.Pattern[str]
|
||||
paths: frozenset[Path] | None = None
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class Violation:
|
||||
path: Path
|
||||
line_number: int
|
||||
label: str
|
||||
text: str
|
||||
|
||||
|
||||
_LEGACY_HOSTING = "git" + "lab"
|
||||
_LEGACY_STABLE_BRANCH = "mas" + "ter"
|
||||
_LEGACY_INTEGRATION_BRANCH = "de" + "v"
|
||||
_LEGACY_EMERGENCY_BRANCH = "hot" + "fix"
|
||||
_LEGACY_BRANCH_MODEL = "git" + "flow"
|
||||
|
||||
RULES = (
|
||||
Rule(
|
||||
"legacy hosting reference",
|
||||
re.compile(rf"\b{_LEGACY_HOSTING}\b", re.IGNORECASE),
|
||||
),
|
||||
Rule(
|
||||
"legacy review wording",
|
||||
re.compile(r"\bmerge\s+request\b", re.IGNORECASE),
|
||||
),
|
||||
Rule(
|
||||
"legacy branch model",
|
||||
re.compile(rf"\b{_LEGACY_BRANCH_MODEL}\b", re.IGNORECASE),
|
||||
),
|
||||
Rule(
|
||||
"legacy stable branch reference",
|
||||
re.compile(rf"\b{_LEGACY_STABLE_BRANCH}\b", re.IGNORECASE),
|
||||
),
|
||||
Rule(
|
||||
"legacy integration branch reference",
|
||||
re.compile(
|
||||
rf"(?<![A-Za-z]){_LEGACY_INTEGRATION_BRANCH}(?![A-Za-z])",
|
||||
re.IGNORECASE,
|
||||
),
|
||||
paths=BRANCH_WORKFLOW_FILES,
|
||||
),
|
||||
Rule(
|
||||
"legacy emergency branch model",
|
||||
re.compile(rf"\b{_LEGACY_EMERGENCY_BRANCH}\b", re.IGNORECASE),
|
||||
paths=BRANCH_WORKFLOW_FILES,
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
def find_violations(
|
||||
file_texts: Iterable[tuple[Path, str]],
|
||||
) -> list[Violation]:
|
||||
violations: list[Violation] = []
|
||||
for path, text in file_texts:
|
||||
for line_number, line in enumerate(text.splitlines(), start=1):
|
||||
for rule in RULES:
|
||||
if rule.paths is not None and path not in rule.paths:
|
||||
continue
|
||||
if rule.pattern.search(line):
|
||||
violations.append(
|
||||
Violation(
|
||||
path=path,
|
||||
line_number=line_number,
|
||||
label=rule.label,
|
||||
text=line.strip(),
|
||||
)
|
||||
)
|
||||
return violations
|
||||
|
||||
|
||||
def _read_monitored_files() -> list[tuple[Path, str]]:
|
||||
return [
|
||||
(path, path.read_text(encoding="utf-8"))
|
||||
for path in MONITORED_FILES
|
||||
if path.exists()
|
||||
]
|
||||
|
||||
|
||||
def main() -> int:
|
||||
violations = find_violations(_read_monitored_files())
|
||||
if not violations:
|
||||
print("GitHub contributor-doc check passed.")
|
||||
return 0
|
||||
|
||||
print(
|
||||
"GitHub contributor-doc check failed.\n"
|
||||
"These files should describe the public GitHub workflow: protected "
|
||||
"`main`, scoped branches, and pull requests back to `main`.\n"
|
||||
)
|
||||
for violation in violations:
|
||||
print(
|
||||
f"- {violation.path}:{violation.line_number}: "
|
||||
f"{violation.label}: {violation.text}"
|
||||
)
|
||||
return 1
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
|
|
@ -131,6 +131,14 @@ vector_strategy = "maxsim_atomic"
|
|||
# requires a restart. Override via EVEROS_MEMORIZE__MODE.
|
||||
mode = "agent"
|
||||
|
||||
# Maximum wall-clock for one memorize() invocation while holding the
|
||||
# per-session lock. On timeout the outer asyncio.timeout cancels the call
|
||||
# and the lock auto-releases so subsequent concurrent /add on the same
|
||||
# session aren't deadlocked. Covers boundary LLM + memcell writes +
|
||||
# synchronous portion of pipeline dispatch.
|
||||
# Override via EVEROS_MEMORIZE__SESSION_LOCK_TIMEOUT_SECONDS.
|
||||
session_lock_timeout_seconds = 360.0
|
||||
|
||||
[knowledge]
|
||||
# Max bytes for an uploaded knowledge document (default 50 MiB). Oversized
|
||||
# uploads are rejected with HTTP 422 before parsing/extraction. Note: the
|
||||
|
|
@ -147,14 +155,6 @@ lambda = 0.1
|
|||
mass_top_m = 50
|
||||
top_k_cap = 100
|
||||
|
||||
# Maximum wall-clock for one memorize() invocation while holding the
|
||||
# per-session lock. On timeout the outer asyncio.timeout cancels the call
|
||||
# and the lock auto-releases so subsequent concurrent /add on the same
|
||||
# session aren't deadlocked. Covers boundary LLM + memcell writes +
|
||||
# synchronous portion of pipeline dispatch.
|
||||
# Override via EVEROS_MEMORIZE__SESSION_LOCK_TIMEOUT_SECONDS.
|
||||
session_lock_timeout_seconds = 360.0
|
||||
|
||||
[clustering]
|
||||
# Geometry-clustering: cosine similarity threshold and time window.
|
||||
# Episodes older than ``time_window_days`` from the newest cluster
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
"""Self-tests for ``scripts/check_github_contributor_docs.py``."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
_REPO_ROOT = Path(__file__).resolve().parents[3]
|
||||
_CHECKER_PATH = _REPO_ROOT / "scripts" / "check_github_contributor_docs.py"
|
||||
|
||||
|
||||
def _load_checker():
|
||||
assert _CHECKER_PATH.exists(), "GitHub contributor-doc checker should exist"
|
||||
spec = importlib.util.spec_from_file_location(
|
||||
"_github_contributor_docs_checker", _CHECKER_PATH
|
||||
)
|
||||
assert spec and spec.loader
|
||||
mod = importlib.util.module_from_spec(spec)
|
||||
sys.modules[spec.name] = mod
|
||||
spec.loader.exec_module(mod)
|
||||
return mod
|
||||
|
||||
|
||||
def test_clean_github_workflow_is_allowed() -> None:
|
||||
checker = _load_checker()
|
||||
|
||||
violations = checker.find_violations(
|
||||
[
|
||||
(
|
||||
Path("CLAUDE.md"),
|
||||
"Create scoped branches from main and open pull requests.\n",
|
||||
)
|
||||
]
|
||||
)
|
||||
|
||||
assert violations == []
|
||||
|
||||
|
||||
def test_legacy_branch_model_terms_are_blocked() -> None:
|
||||
checker = _load_checker()
|
||||
stable_branch = "mas" + "ter"
|
||||
integration_branch = "de" + "v"
|
||||
legacy_review = "merge " + "request"
|
||||
branch_model = "Git" + "Flow"
|
||||
emergency_branch = "hot" + "fix"
|
||||
|
||||
violations = checker.find_violations(
|
||||
[
|
||||
(
|
||||
Path("CLAUDE.md"),
|
||||
f"{stable_branch} is stable and {integration_branch} is integration.\n",
|
||||
),
|
||||
(Path("CONTRIBUTING.md"), f"Open an internal {legacy_review}.\n"),
|
||||
(
|
||||
Path(".claude/skills/pr/SKILL.md"),
|
||||
f"{branch_model} {emergency_branch} path.\n",
|
||||
),
|
||||
]
|
||||
)
|
||||
|
||||
assert [(v.path.as_posix(), v.label) for v in violations] == [
|
||||
("CLAUDE.md", "legacy stable branch reference"),
|
||||
("CLAUDE.md", "legacy integration branch reference"),
|
||||
("CONTRIBUTING.md", "legacy review wording"),
|
||||
(".claude/skills/pr/SKILL.md", "legacy branch model"),
|
||||
(".claude/skills/pr/SKILL.md", "legacy emergency branch model"),
|
||||
]
|
||||
|
||||
|
||||
def test_real_repo_has_no_legacy_contributor_doc_residue() -> None:
|
||||
checker = _load_checker()
|
||||
|
||||
assert checker.main() == 0
|
||||
Loading…
Reference in New Issue