Knowledge layer v2: notes, update-in-place, stats, tags#4
Merged
Conversation
New entry type 'note' for general-purpose knowledge storage with optional content payload and MIME type. New tools: - remember: create notes (permanent, tagged, searchable) - update_entry: update knowledge types in place with _changelog tracking (status/alert/suppression are immutable) - get_stats: entry counts by type, sources, total - get_tags: all tags with usage counts (prevents tag drift) Enhanced get_knowledge with include_history param (false/true/only) to control _changelog visibility in results. 148 tests, all passing. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Document new tools (remember, update_entry, get_stats, get_tags), note entry type, include_history param, and changelog tracking. Update tool count from 14 to 18, test count from 124 to 148. Remove 'first-class knowledge entry type' from not-yet-implemented. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This was referenced Mar 23, 2026
cmeans
pushed a commit
that referenced
this pull request
Mar 31, 2026
1. Remove pull_policy: always — contradicts build: . (SUBSTANTIVE #1) 2. Default Ollama volume to ~/awareness-ollama-oauth to avoid concurrent access with production (SUBSTANTIVE #2) 3. Parameterize AWARENESS_PUBLIC_URL with env var (OBSERVATION #3) 4. Replace real WorkOS domain with placeholder in template (NIT #4) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cmeans
pushed a commit
that referenced
this pull request
Apr 1, 2026
1. Remove pull_policy: always — contradicts build: . (SUBSTANTIVE #1) 2. Default Ollama volume to ~/awareness-ollama-oauth to avoid concurrent access with production (SUBSTANTIVE #2) 3. Parameterize AWARENESS_PUBLIC_URL with env var (OBSERVATION #3) 4. Replace real WorkOS domain with placeholder in template (NIT #4) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cmeans
pushed a commit
that referenced
this pull request
Apr 7, 2026
- Fix maintenance deploy: sudo drops env vars, use sudo -u awareness bash -c with sourced env to preserve AWARENESS_DATABASE_URL (#1 blocker) - Fix double-update of first node in maintenance deploy: update_node runs once, remaining nodes loop skips first entry (#2) - Add usage comment to create-ct200.sh (#4) - Update deployment plan to match fixed script Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cmeans
pushed a commit
that referenced
this pull request
Apr 7, 2026
- #1: Specify two-step re-init (synthetic initialize + replay original) using stored registry metadata (capabilities, client_info, protocol_version) - #2: Add session_redirects table for old→new session_id mapping with 5-min grace period. Middleware transparently rewrites request headers. - #3: Clarify sliding-window TTL — touch() extends expires_at - #4: Document HAProxy stick table gap after rotation (self-healing) - #5: Note deliberate LOGGED deviation from issue with rationale - #6: Specify lookup() filters expired sessions (no re-init for zombies) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
cmeans-claude-dev Bot
added a commit
that referenced
this pull request
Apr 21, 2026
…334) (#351) Closes [#334](#334). Also closes CodeQL alerts #1, #2, #3 (three flags of `actions/missing-workflow-permissions` in `ci.yml`). ## Summary Two workflow-hardening fixes bundled because they're the same theme (least-privilege + contributor-controlled-input discipline) and both surfaced from the same security review: ### 1. `pr-labels.yml` — cascade the `#333` env-routing pattern (closes #334) Three job steps in `pr-labels.yml` (`on-push`, `on-unlabel`, `on-label`) previously inlined contributor-visible fields as `${{ ... }}` expressions inside `run:` bodies: ```yaml # Before run: | PR=${{ github.event.pull_request.number }} REPO=${{ github.repository }} HEAD_SHA=${{ github.event.pull_request.head.sha }} # ... shell script references PR / REPO / HEAD_SHA ``` Now they route through step-level `env:` and are referenced as shell variables: ```yaml # After env: PR: ${{ github.event.pull_request.number }} REPO: ${{ github.repository }} HEAD_SHA: ${{ github.event.pull_request.head.sha }} run: | # ... shell script references "$PR" / "$REPO" / "$HEAD_SHA" ``` **Not a currently-exploitable bug.** The `on: pull_request:` trigger means fork PRs get a read-only `GITHUB_TOKEN` — the `gh pr edit --add-label` / `--remove-label` calls would be rejected from a fork PR regardless of what `PR`/`REPO`/`HEAD_SHA` contained. And all three values are typed (numeric PR, repo name validated by GHA, hex SHA) — none come from user-authored text like titles or bodies. **Why change it anyway**, per #334's rationale: - **Trigger-drift risk.** If `pr-labels.yml` ever switches to `pull_request_target` (to allow label automation on fork PRs), the same injection class that #333 closed on `pr-labels-ci.yml` reappears — and now the hardening would already be in place. - **Parameterization-drift risk.** A future maintainer adding a contributor-authored string field (label name, PR title fragment, branch name) to a `run:` block won't be prompted to route via `env:` first because the file already establishes the inline `${{ ... }}` style as "fine here." - **Cascade consistency.** `pr-labels-ci.yml` uses env-routing since #333; having the sibling workflow use a different style is a readability cost for anyone auditing the repo. ### 2. `ci.yml` — add workflow-level `permissions: contents: read` (closes CodeQL #1/#2/#3) `ci.yml` had no `permissions:` block at workflow or job level, so all three jobs (`lint`, `typecheck`, `test`) inherited whatever repo-level default `GITHUB_TOKEN` scope is configured. CodeQL flagged this three times (one per job). Fix: declare `permissions: contents: read` at the workflow level. Every job inherits read-only content access, which is sufficient for lint / typecheck / pytest / codecov. No job actually needs write access to anything. ## Audit sweep results While touching workflow files, checked all six for missing `permissions:`: | Workflow | Had `permissions:`? | This PR's action | |----------|---------------------|------------------| | `ci.yml` | No (CodeQL flagged 3x) | Added `contents: read` at workflow level | | `docker-publish.yml` | Yes, line 23 | No change | | `docker-smoke.yml` | Yes, line 40 (from #350) | No change | | `pr-labels-ci.yml` | Yes, line 35 (from #333) | No change | | `pr-labels.yml` | Yes, line 26 | No change to permissions block; env-routing changes only | | `qa-gate.yml` | Yes, line 24 | No change | `ci.yml` was the last gap. Sweep is complete. ## Scope - `.github/workflows/ci.yml` — `+7 lines` (permissions block with inline rationale comment) - `.github/workflows/pr-labels.yml` — `+10, -11` (three `run:` bodies lose two shell-assignment lines each; three `env:` blocks gain two-three entries each; explanatory comment added in the `on-unlabel` case) - `CHANGELOG.md` — `+4 lines` (new `### Security` subsection under `[Unreleased]`) No source, no tests, no migrations. ## References - Closes [#334](#334) - Closes CodeQL alerts #1, #2, #3 (`actions/missing-workflow-permissions` on `ci.yml:27/41/53`) - Cascade source: PR [#333](#333) (same pattern for `pr-labels-ci.yml`, which closed #332) - Related CodeQL alerts not addressed by this PR: #5/#6/#7/#8 (OAuth clear-text logging in `oauth.py` and `oauth_proxy.py`) — separate audit PR, coming next. #4 (socket bind in tests) — dismiss via UI. ## QA ### Prerequisites None. Pure workflow-YAML changes. ### Automated checks - `lint`, `typecheck`, `test (3.10/3.11/3.12)` — none touch YAML, should remain green. - `CodeQL (actions)` — will re-scan `ci.yml` and `pr-labels.yml` on this PR. Expected outcome: alerts #1/#2/#3 flip to "fixed" on merge; no new alerts introduced. - `docker-smoke` — not triggered (no changes under `Dockerfile` / `pyproject.toml` / `uv.lock` / `.dockerignore`). ### Manual tests 1. - [x] **Both workflow files parse.** ``` python3 -c "import yaml; [yaml.safe_load(open(f)) for f in ['.github/workflows/ci.yml', '.github/workflows/pr-labels.yml']]; print('OK')" ``` Expected: `OK`. 2. - [x] **`ci.yml` now has `permissions: contents: read`.** ``` grep -A1 '^permissions:' .github/workflows/ci.yml ``` Expected: `permissions:` header followed by ` contents: read`. 3. - [x] **No contributor-controlled inputs in `pr-labels.yml` `run:` bodies.** ``` awk '/^[[:space:]]+run: \|/,/^[[:space:]]+- name:|^[[:space:]]{2,6}[a-z-]+:$/' .github/workflows/pr-labels.yml | grep -nE '\$\{\{ *github\.(event|repository|head_ref)' || echo "(none — good)" ``` Expected: `(none — good)`. All `github.event.*` / `github.repository` references are now in `env:` blocks (and in job-level `if:` conditionals, which is safe context). 4. - [x] **All six workflows now have `permissions:`.** ``` for f in .github/workflows/*.yml; do if ! grep -q '^permissions:\|^ permissions:\|^ permissions:' "$f"; then echo "$f: MISSING permissions" fi done echo "(if no 'MISSING' lines above, sweep is complete)" ``` Expected: no `MISSING` lines. 5. - [x] **Label automation still functions on this PR.** When I push, `pr-labels.yml`'s `on-push` should reset labels to `Awaiting CI` and strip any stale QA labels. When `Dev Active` is removed, `on-unlabel` should promote to `Ready for QA` after CI passes. Empirically validated if the label transitions on this PR itself behave identically to recent merged PRs (self-test). 6. - [x] **`permissions: contents: read` doesn't break anything.** Lint / typecheck / pytest / codecov upload only need read access to `GITHUB_TOKEN` — none of them push labels, create comments, or mutate repo state. If any of the existing CI checks start failing on this PR with "resource not accessible" errors, that's a signal the permissions block is too tight (unlikely, but the empirical test is: does this PR's CI go green?). 7. - [x] **Diff review.** ``` git diff --stat origin/main ``` Expected: `.github/workflows/ci.yml` (+7), `.github/workflows/pr-labels.yml` (+10, -11), `CHANGELOG.md` (+4). Nothing else. ### Acceptance - ✅ `#334` — symmetric env-routing cascade landed in `pr-labels.yml` - ✅ CodeQL `#1`, `#2`, `#3` — `ci.yml` now has explicit `permissions:` - ☐ CodeQL re-scan confirmation — post-merge, the three alerts flip from Open → Fixed automatically on the next `Analyze (actions)` run against `main` Post-merge, also worth a look at CodeQL's /security/code-scanning dashboard to confirm Open count drops from 8 → 5 (just the four OAuth-logging + the one test-file socket-bind remaining). Co-authored-by: cmeans-claude-dev[bot] <3223881+cmeans-claude-dev[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Merged
cmeans-claude-dev Bot
added a commit
that referenced
this pull request
Apr 22, 2026
…tor link (#357) Closes the high-severity docs gaps from the 2026-04-21 contribution-safety audit (`audit-contribution-safety-2026-04-21` in awareness). First of three planned PRs from that audit; #B (ruleset changes) and #C (workflow SHA-pinning) follow separately. ## Summary Makes contributor expectations discoverable at the moment a contributor is about to open a PR, not buried in `CLAUDE.md` where only maintainers look. - **`.github/PULL_REQUEST_TEMPLATE.md`** — standard template auto-populated on PR creation. - **`CONTRIBUTING.md`** — three new sections (engagement-first, AI disclosure, secrets). - **`README.md`** — new `## Contributing` section pointing at `CONTRIBUTING.md` and `SECURITY.md`. - **`CHANGELOG.md`** — `### Added` / `### Changed` entries under `[Unreleased]`. ## What the template prompts for - **Linked issue** (engagement-first) — with a comment-block reminder that typo/doc fixes are exempt and that issues stay permissive, so bug reporting isn't gated. - **Summary, scope** — same as the maintainer-side convention already in use. - **AI-assistance disclosure checkboxes** — four categories: none, code generation, review assist, PR body / commit messages. Mirrors the new CONTRIBUTING section's stance: disclosure, not prohibition. - **QA section** — prerequisites + MCP-tool-driven manual tests. Consistent with `CLAUDE.md`'s requirement that testing go through MCP tools, not raw HTTP. - **Checklist** — CHANGELOG entry, README/data-dictionary update if affected, no-secrets affirmation, local `ruff`/`mypy`/`pytest`, CLA signature via `cla-assistant` bot. ## Why these three places The audit's concern #4 was "setting contributor expectations upfront so people self-filter." Three discovery surfaces: 1. **PR template** — fires at the moment of PR creation, highest-leverage. 2. **CONTRIBUTING.md** — canonical source of truth, linked from PR template. 3. **README.md** — for contributors browsing the repo landing page before deciding to file anything. Previously only the CLA flow was surfaced in CONTRIBUTING.md, and neither CONTRIBUTING.md nor SECURITY.md was linked from the README. ## Risks and unknowns - **PR template friction.** A long template can discourage drive-by contributions we actually want (small doc fixes). Counter-weighted by: the typo/doc-fix exemption is in the linked-issue comment block, and most sections are short prompts (1-3 sentences) rather than formal fields. - **AI disclosure phrasing.** The tone is deliberately non-judgmental ("disclosure, not prohibition"). If a contributor reads it as gatekeeping, the language is too heavy. Easy to soften in a follow-up based on real feedback. - **"No secrets" duplicated between CONTRIBUTING and the PR template checklist.** Intentional redundancy — CONTRIBUTING explains _why_ and the checklist makes the affirmation explicit. Not actually contradictory. ## Scope - `.github/PULL_REQUEST_TEMPLATE.md` — **new file**, 76 lines - `CONTRIBUTING.md` — `+39, -0` (three new sections inserted at natural points) - `README.md` — `+4, -0` (new `## Contributing` block above `## License`) - `CHANGELOG.md` — `+11, -0` (three entries under `[Unreleased]`) No source, no tests, no workflows, no compose changes, no migrations. Pure docs. ## References - Audit report: awareness entry `audit-contribution-safety-2026-04-21` (id `0c79b026`) - Originating handoff: awareness intention `598956c6` (from claude.ai, 2026-04-19) - Phase 2 follow-ons: ruleset changes (PR #B), workflow SHA-pinning (PR #C), manual Settings UI tightening ## QA ### Prerequisites None. Pure docs change. ### Automated checks - `lint`, `typecheck`, `test (3.10–3.13)` — docs-only change; expected green, no behavior exercise. - `docker-smoke` — **skipped** (no `Dockerfile` / `pyproject.toml` / `uv.lock` / `.dockerignore` / workflow-file matching its trigger change). - `CodeQL (actions)` — no workflow files touched; skipped or no-op. - `codecov/patch` — docs-only; expected to report 100% (no coverable lines changed). - `license/cla` — should stay green (maintainer-authored commit). ### Manual tests 1. - [ ] **PR template renders on a new PR.** Open a throwaway PR on any branch after this merges and verify the body pre-populates with the template (GitHub auto-loads `.github/PULL_REQUEST_TEMPLATE.md`). _QA: not verifiable pre-merge; file placement at `.github/PULL_REQUEST_TEMPLATE.md` is correct so GitHub will auto-load. Post-merge verification expected to pass._ 2. - [x] **CONTRIBUTING.md section order and wording are correct.** Read through the rendered markdown: - "Before opening a pull request" sits above "Development setup" ✓ - "AI-assistance disclosure" and "Do not commit secrets" sit below "Code style" ✓ - Engagement-first wording doesn't read as gatekeeping (has the "typo/doc-fix exempt" + "issues stay permissive" softeners) 3. - [x] **README `## Contributing` section renders between "How it's built" and "License"**, with both `CONTRIBUTING.md` and `SECURITY.md` as clickable links. 4. - [x] **No stray file changes.** `git diff --stat origin/main` shows exactly the four files above (`.github/PULL_REQUEST_TEMPLATE.md`, `CONTRIBUTING.md`, `README.md`, `CHANGELOG.md`). Nothing else. ### Acceptance - ✅ CI green (all above automated checks) - ✅ Template prompts for linked issue (engagement-first) - ✅ Template prompts for AI-assistance disclosure - ✅ Template includes no-secrets affirmation and QA section - ✅ CONTRIBUTING.md has engagement-first, AI-disclosure, secrets sections - ✅ README.md links to both CONTRIBUTING.md and SECURITY.md - ✅ Single-concern; no code / test / workflow changes 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: cmeans-claude-dev[bot] <3223881+cmeans-claude-dev[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
cmeans-claude-dev Bot
added a commit
that referenced
this pull request
Apr 28, 2026
…#378) (#410) ## Summary Closes #378. Two stale-label traps in `pr-labels-ci.yml` fixed symmetrically; both rooted in narrow outer guards that only fired on `Awaiting CI`, missing the post-`CI Failed` recovery arc and the `Ready for QA → CI Failed` regression arc. | Job | Today | Now | | --- | --- | --- | | `on-ci-pass` | Promotes only when `Awaiting CI` is present | Promotes when `Awaiting CI` OR `CI Failed` is present | | `on-ci-fail` | Adds `CI Failed` only when `Awaiting CI` is present | Adds `CI Failed` when `Awaiting CI` OR `Ready for QA` is present | ### Bug 1 — `CI Failed → CI pass` silently no-ops (issue #378) Reproduction trail in #377 (2026-04-22): a lint-failing push moved labels to `CI Failed`; the fix-up push made CI go green; `on-ci-pass` fired and ran, but its outer `if echo "$LABELS" | grep -q "^Awaiting CI$"` was false (only `CI Failed` was present), so it silently no-op'd. PR sat at `CI Failed` while CI was actually green. Required a manual `gh pr edit --remove-label "CI Failed" --add-label "Ready for QA"` to unstick. ### Bug 2 — `Ready for QA → CI re-fail` keeps the green label (symmetric) Mirror trap on `on-ci-fail`: a CI re-run on a PR sitting at `Ready for QA` (e.g., manual re-trigger after a flake, or a workflow change forcing a re-run) that turns red leaves the PR labelled `Ready for QA` because the outer `if echo "$LABELS" | grep -q "^Awaiting CI$"` is false. The status check goes red but the label still says ready — QA might pick it up assuming CI is green. ### Review-state preservation Broadening the triggers introduces a new risk: if a `QA Active` / `Ready for QA Signoff` / `QA Approved` label coexists with a CI label (race, or manual mistake), the broader trigger could overwrite review-machine state with `Ready for QA` (on pass) or `CI Failed` (on fail). To prevent that, both jobs now short-circuit explicitly when any of those three labels is present: ```bash for QA_STATE in "QA Active" "Ready for QA Signoff" "QA Approved"; do if echo "$LABELS" | grep -q "^$QA_STATE$"; then echo "$QA_STATE present — skipping (review in progress)" exit 0 fi done ``` Rationale: review state advances independently of CI re-runs. A passing or failing CI re-run on a PR that's already in QA review is visible via the check itself; the label transition would be redundant on success and destructive on failure. `Dev Active` short-circuit preserved unchanged. ### Safety - Trigger remains `workflow_run` — base-branch context, immune to PR-branch edit attacks (same protection class as the `pull_request_target` migration in #409). - No new contributor-controlled inputs. Label list still read via `gh pr view --json labels` (repo-owned strings, not fork-controlled). - All grep patterns remain anchored (`^Label$`) so labels like `Awaiting CI Failed` (if one ever existed) cannot accidentally satisfy a `^Awaiting CI$` check. - Existing env-routing of `HEAD_BRANCH` / `RUN_ID` / `PR` / `REPO` (hardened in #332/#333) is unchanged. Nothing I add interpolates new contributor-controlled values into shell. ### State-machine trace (full) Pre-state → CI conclusion → resulting transition (✓ = covered, ✗ = no-op, * = new): | Pre-state | CI = success | CI = failure | | --- | --- | --- | | `Awaiting CI` | → `Ready for QA` ✓ | → `CI Failed` ✓ | | `CI Failed` | → `Ready for QA` ✓* | stays `CI Failed` ✓ | | `Ready for QA` | stays `Ready for QA` ✓ | → `CI Failed` ✓* | | `Dev Active` | no-op (skip) ✓ | no-op (skip) ✓ | | `QA Active` | no-op (skip) ✓* | no-op (skip) ✓* | | `Ready for QA Signoff` | no-op (skip) ✓* | no-op (skip) ✓* | | `QA Approved` | no-op (skip) ✓* | no-op (skip) ✓* | The * entries are new in this PR. The `Dev Active` and "no pre-state" cases were already correct. ## Test plan Workflow YAML only. No tests to add. ## QA ### Prerequisites - None — pure workflow YAML change. ### Manual tests 1. - [x] **Workflow YAML parses cleanly.** Confirm the Actions tab on this PR shows no parse-error annotations on `pr-labels-ci.yml`. 2. - [x] **Diff matches the state-machine trace table above.** Read `.github/workflows/pr-labels-ci.yml` head-to-toe; for each row of the trace, confirm the corresponding code path emits the expected transition (or skip). 3. - [x] **#409 migration live-validation (deferred from #409 QA test plan #4).** This is the first PR opened against `main` since the `pr-labels.yml` / `qa-gate.yml` migration to `pull_request_target`. Confirm: - `pr-labels.yml` `on-push` fired on opening: `Awaiting CI` was applied automatically (no manual addition required this time). - `qa-gate.yml` posted a `QA Gate` status on this PR's head SHA from app `15368` (GitHub Actions). Visible in the status-check rollup. - These two observations together confirm #409's migration works end-to-end on a real PR — not just on the introduction PR's bootstrap-skipped path. 4. - [ ] **Verification of the bug-fix itself is post-merge.** `workflow_run` triggers always run from the default branch (per the `LIMITATION` comment at the top of `pr-labels-ci.yml`), so this PR's changes do not run on this PR. The natural validation is the next CI-fail-then-pass PR after this lands — when that happens, the PR should auto-promote `CI Failed → Ready for QA` without manual intervention. Reviewer should add a follow-up note here (or in the awareness milestone for this PR) once that natural validation occurs. ### Out-of-scope follow-ups (not for this PR) - The `dismiss_stale_reviews_on_push` setting interacts with these transitions in subtle ways (review approvals get auto-dismissed on push, then CI re-runs). No change proposed; just flagging for awareness. - A future enhancement could add a `QA Invalidated` style label for the case where CI re-fails on a PR in QA review, but doing so requires designing the QA recovery path. Out of scope for #378. Co-authored-by: cmeans-claude-dev[bot] <272174644+cmeans-claude-dev[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
noteentry type: General-purpose permanent knowledge with optionalcontentpayload and MIMEcontent_type. The catch-all for anything that isn't an operational pattern or time-limited context.remembertool: Create notes — personal facts, project notes, skill backups, config snapshots.update_entrytool: Update knowledge entries (note/pattern/context/preference) in place with_changelogtracking. Status/alert/suppression are immutable.get_statstool: Entry counts by type, sources list, total count.get_tagstool: All tags with usage counts — prevents tag drift.get_knowledgeenhanced: Newinclude_historyparam (false/true/only) controls_changelogvisibility.Design decisions
notevs other names: chosen as the simplest general-purpose name; may evolveremembervsadd_note:rememberis more natural for agent interaction_changelogstored inline in entry data, not a separate table — lightweight, co-located with the entryinclude_history="only"returns only entries with changelog — useful for "what's changed?" queriesTest plan
remembercreates entries visible inget_knowledgeupdate_entryrejects immutable typesget_tagsreturns correct countsinclude_historyfiltering works🤖 Generated with Claude Code