Skip to content

feat(tags): add unified artifact and memory entry tags - #1472

Open
Teingi wants to merge 2 commits into
oceanbase:masterfrom
Teingi:codex/artifact-tags-implementation
Open

feat(tags): add unified artifact and memory entry tags#1472
Teingi wants to merge 2 commits into
oceanbase:masterfrom
Teingi:codex/artifact-tags-implementation

Conversation

@Teingi

@Teingi Teingi commented Sep 5, 2026

Copy link
Copy Markdown
Member

Which issue or RFC does this PR close?

Closes #1466.

Implements the design proposed in RFC #1467, which is tracked separately. Based on upstream master at 74b961fbb07165595314726715d412a3d0d90589.

Rationale for this change

Customers need to classify reusable knowledge by customer, project, or workflow and find the matching resources without editing their content. Artifact-level labels alone cannot distinguish individual entries within a Memory.

Tags are mutable, Scope-local discovery metadata attached to logical identities. They do not create content revisions, change lineage or embeddings, grant permissions, or become model instructions.

What changes are included in this PR?

  • Add one pc_artifact_tags assignment table for Memory, Experience, Skill, Handoff, and nested logical MemoryEntry targets. The owning Artifact head provides the foreign-key and write-serialization boundary; MemoryEntry validity comes from the authoritative current manifest, including inactive entries.
  • Add deterministic Unicode normalization, bounded tag sets, target-bound opaque ETags, conditional GET, and compare-and-swap replacement. Missing If-Match returns 428; stale or wrong-target validators return 412.
  • Add cross-family exact all/any queries with current Artifact references or Memory citations, inactive-target filtering, and signed cursors bound to Scope, filters, caller, and expiry.
  • Filter Artifact lists, Memory-entry lists, and Memory FTS/vector candidates before limits and fusion. Tagged vector queries use exact distance ordering over eligible entries on SQLite and OceanBase.
  • Extend OpenAPI, generated contracts, Python Client, and JavaScript clients. Preserve response ETags and repeated tag query parameters; restore the missing OpenCode query-string helper and rebuild the checked-in plugin bundles.
  • Add a bilingual Dashboard editor and tag lookup with conflict-safe input preservation, plus English and Chinese usage and backup guidance.
  • Add lifecycle, Unicode, isolation, concurrent-write, pagination, pre-candidate filtering, projection-rebuild, and publication tests, plus opt-in real-model acceptance for both databases.

Are there any user-facing changes?

  • Five new operations expose Artifact/MemoryEntry tag GET/PUT and cross-family tag queries. Existing list/search requests gain optional tag filters; unfiltered behavior is preserved.
  • Users can edit tags and find matching logical targets from the Dashboard overview. Artifact tags and MemoryEntry tags are independent.
  • Tags stay attached to logical IDs and survive inactive MemoryEntry state and projection rebuilds. Publishing an Artifact to another Scope does not copy its tags.
  • Database initialization creates one additional table; existing resources start with empty tags and require no backfill. Backups must include this table after Artifact heads. A 32-byte key fingerprint keeps indexes within the OceanBase/MySQL key-size budget, while queries also compare the complete normalized key.
  • Tagged vector retrieval prioritizes exact eligibility and can cost more than unfiltered approximate search. Custom backends without tag-filter support reject the option explicitly.

How was this change tested?

Validation used Python 3.14 and Node.js 22. Commands below were run during implementation; the final source/type and staged-diff checks were repeated before submission.

  • pytest tests/e2e/test_real_artifact_tags.py --run-real-e2e -q --tb=short --show-capture=no: 2 passed. Used the configured real generation and embedding providers, OceanBase, and SQLite. Covered generated Memory, four Artifact families, concurrent ETag writes, FTS/vector/hybrid retrieval, inactive entries, and publication without tag copying. OceanBase runs created and dropped only isolated test databases; SQLite used temporary files. Existing business data and credentials were not changed or committed.
  • pytest tests/e2e/test_artifact_tags.py tests/builtin/test_tags.py tests/builtin/persistence/test_records.py -q: 24 passed. Includes retrieving an eligible tagged entry outside the first 32 unfiltered results in all three search modes.
  • pytest tests -q --tb=short --show-capture=no: 1343 passed, 19 skipped, 1 failed. The remaining OpenCode Host callback timeout was also reproduced from an untouched 74b961f snapshot with its original plugin bundle; stdout/stderr were empty and no capture hook arrived within 30 seconds.
  • pytest src/powercontext --doctest-modules -q: 1 passed.
  • make api-generate-check js-api-generate-check contract-test: passed, including 38 contract tests.
  • DSH: 68 unit tests + 8 live HTTP end-to-end tests passed, and plugin build passed.
  • OpenCode: 23 tests passed, typecheck and plugin build passed.
  • Pi: 49 tests passed with pnpm exec vitest run --testTimeout=30000; typecheck passed. Its real CLI cold-start test exceeded the default 5-second timeout and passed with the 30-second window.
  • make docs-test: passed, including lint and the bilingual static site build (556 pages).
  • Real Chromium interaction: save, exact lookup, inactive-entry editing, literal rendering of HTML-shaped labels, stale-ETag conflict with preserved input, clear/reload, and Chinese UI verified. The temporary Server and browser session were closed.
  • ruff check src tests, ruff format --check src tests, ty check src/powercontext tests --output-format concise, uv lock --locked, and git diff --cached --check: passed.
  • Full prek run -a is not green: the existing Codex hooks have three unresolved scripts.scope_binding imports. All other hooks passed with SKIP=ty-check. A standalone DSH tsc --noEmit also reports existing .ts import configuration and unrelated test typing errors; the configured build and runtime tests pass. These unrelated integration configuration issues are not hidden or included as tag changes.

AI usage statement

Implemented, documented, and validated with OpenAI Codex, including real provider/database and browser testing. No credentials, environment files, or temporary database contents are included in this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFC: Add unified tags for Artifacts and Memory entries

1 participant