diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..6d84e9b7 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,188 @@ +# Contributing to ContextEngine + +Thanks for taking the time to look at this project. + +Before you write code, please read this page. ContextEngine holds a stricter +evidence bar than most repositories its size, and the difference is not style — +it is the point of the project. A contribution that adds a useful feature but +weakens an invariant will be declined. + +## The one rule that explains all the others + +**Security is a veto, not a score.** + +Three invariants must hold, and no feature benefit offsets a failure in any of +them: + +- Unauthorized Evidence leaked = **0** +- Wrong-Organization effect = **0** +- Missing tenant context = **fail closed, always** + +A second rule follows from the first: **a capability is not "done" because it +runs — it is done when executable evidence proves its exact boundary.** +Anything unproven stays labeled `NOT_ACTIVE`, including in the service's own +`/health` response. Please do not "helpfully" remove a `NOT_ACTIVE` marker; it +is load-bearing. See [STATUS.md](./STATUS.md). + +## Before you start + +1. **Check the issue tracker.** Issues and PRDs live in + [GitHub Issues](https://github.com/stone16/context-engine/issues). Read the + full body, labels, and comments before acting on an existing issue. +2. **Open an issue before a large PR.** External pull requests are not a triage + surface for feature requests — an unsolicited large PR is likely to be + declined on scope alone, however good the code is. +3. **Read the domain glossary.** [CONTEXT.md](./CONTEXT.md) is the repository's + authority on terms like `CandidateRef`, `AuthorizedProjection`, + `SourceAclEvidence`, and `TrustedDeliveryContext`. Using these words loosely + in code or review is a real source of bugs here. + +### Triage labels + +| Label | Meaning | +|---|---| +| `needs-triage` | Maintainer evaluation is required | +| `needs-info` | Waiting for reporter information | +| `ready-for-agent` | Fully specified and AFK-agent ready | +| `ready-for-human` | Human implementation or judgment is required | +| `wontfix` | The work will not be actioned | + +## Development setup + +Prerequisites and their sources of truth are listed under +[Quick start](./README.md#quick-start) in the README. + +```bash +make install +make db-up +``` + +## The verification contract + +**Never claim a change works without running the commands and reading the real +output.** Fabricated or assumed verification output is the one contribution +behavior that will get a PR closed without further review. + +Run the full gate — the same one CI runs — before opening a PR: + +```bash +make check +``` + +`make check` requires `make db-up` first, and covers: build, Ruff, strict mypy, +TypeScript typecheck, OpenAPI freeze check, SDK generate/build/test/pack, +ActionPlane and BotDelivery build and tests, Python unit tests, the security +catalog, the process smoke suite, the real-PostgreSQL integration harness, and +the M0 security gate. + +For faster inner loops: + +```bash +make lint # Ruff +make typecheck # strict mypy + TS +make test # Python unit tests +make integration # real-PostgreSQL integration/security harness +make security-gate # M0 security veto gate +``` + +When you are done, stop the harness: + +```bash +make db-down +``` + +## Writing tests + +Tests are not a coverage exercise here — they are the evidence the project +ships on. Two expectations go beyond the usual: + +- **A test must encode the business invariant it protects,** not merely the + current behavior. If a test still passes after the meaningful rule changes, + it is a shallow test. +- **Runtime tests use the highest public seam available** — HTTP or the + generated SDK — and must prove the chain + `CandidateRef → AuthorizationKernel → AuthorizedProjection`. A test that lets + a raw candidate reach a content-bearing consumer is testing the wrong thing. + +Negative cases matter as much as positive ones: cross-Organization, denied +same-Organization, nonexistent candidates, tampering, replay, expiry, and +concurrent losers should all be provably zero-effect. + +## Architectural boundaries + +These are not preferences. Changes that cross them will be asked for an ADR +first, or declined. + +- **The Runtime path is sealed, not merely wired.** No feature flag, alternate + composition, no-op dependency, or direct retriever-to-assembler path may + bypass the `AuthorizationKernel`, PackageBudget, provenance, or audit gates. +- **Authorization precedes anything content-bearing.** Indexes return + `CandidateRef` only. Hydration, reranking, relevance models, and assembly + accept `AuthorizedProjection` only. Every parent/neighbor expansion is + re-authorized. +- **`Weak` ACL evidence is never a fallback.** It is permitted only where a + source genuinely lacks finer-grained ACL semantics. A failed `Live` or + `Mirrored` check fails closed. +- **External effects go through `ActionPlane.prepare` then `perform`,** each + with its own org-scoped, audience- and payload-bound, one-shot ticket. Never + reuse a create ticket for an edit or send. +- **Index and cache filters never make authorization decisions.** +- **No secrets, `.env` values, or credentials in commits** — reference a single + live source. Do not hardcode volatile values (URLs, ports, versions) in prose; + point to their source of truth. + +### Zero code copying + +The design draws on architectural study of **Dify**, **RAGFlow**, **MaxKB**, and +**Onyx**, limited to observable behavior, interface shape, test oracles, and +product workflows. **Do not copy code from them, in any amount.** Public +reference claims must trace to the +[evidence baseline](./docs/research/2026-07-19-four-public-repositories-evidence.md). +Research from outside this repository may inform your reasoning, but must never +be cited or linked as public provenance. + +## Architecture Decision Records + +Any non-obvious decision is recorded as an ADR under +[`docs/decisions/`](./docs/decisions/README.md) — there are 60 of them, and they +are the authority on boundaries, dependency direction, forbidden shortcuts, and +revisit triggers. + +Write a new ADR when your change alters a boundary, introduces a dependency +direction, or closes off an option that a future contributor might reasonably +want. Follow the numbering and shape of the most recent accepted ADRs. + +## Pull requests + +**Commits.** One concern per commit. Use the prefixes already in the history: +`feat:`, `fix:`, `docs:`, `chore:`, `refactor:`, `style:`, or a domain prefix +such as `supply:`, `runtime:`, `delivery:`, `bot:`. + +**Before you open the PR, confirm:** + +- [ ] The change does what the issue asked, and edge cases are considered. +- [ ] `make check` passes, and you have the real output — not an assumption. +- [ ] Runtime tests prove `CandidateRef → AuthorizationKernel → + AuthorizedProjection`; no raw candidate reaches a content-bearing consumer. +- [ ] No secrets or volatile values baked into code or docs. +- [ ] Any non-obvious decision is recorded as an ADR. +- [ ] Capability claims match reality — anything unproven is still `NOT_ACTIVE`, + and [STATUS.md](./STATUS.md) is updated if a boundary moved. + +**In the PR description**, state plainly what you verified and what you did not. +If you skipped something, say so. Surfacing uncertainty is always preferred to +hiding it. + +## Scope discipline + +Touch only what the task requires. Please do not "improve" adjacent code, +comments, or formatting in the same PR — it makes the security-relevant diff +harder to review, which is a real cost in this repository. Match existing +conventions even where you would have chosen differently; if you think a +convention is harmful, raise it as its own issue rather than forking it +silently. + +## License + +By contributing, you agree that your contributions are licensed under the +[Apache License 2.0](./LICENSE). diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..701a2605 --- /dev/null +++ b/NOTICE @@ -0,0 +1,6 @@ +ContextEngine +Copyright 2026 stone16 + +Licensed under the Apache License, Version 2.0 (the "License"). +You may obtain a copy of the License in the LICENSE file distributed with this +work, or at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/README.md b/README.md index 1694fa10..c50dda15 100644 --- a/README.md +++ b/README.md @@ -1,321 +1,346 @@ # ContextEngine -> A multi-tenant context delivery engine: connect your team's knowledge sources -> upstream, deliver **authorized, evidence-backed, budget-bounded** -> ContextPackages to agents and IM bots downstream. - -多租户上下文交付引擎——上游连接团队知识源(飞书 / Slack / Google Docs / -企业微信),下游把「经过授权、带证据、有预算」的 ContextPackage 交付给 agent -应用与 IM bot(飞书群聊问答优先)。 - -**当前状态**:M0 工程骨架已启动。API 和独立 Supply worker 可运行, -[`compose.yaml`](./compose.yaml) 固定的真实 PostgreSQL + pgvector 测试底座可复现; -Organization 安全根、全局 User、Organization-scoped Membership 与一张代表性 -tenant-owned 表的非 owner FORCE RLS 隔离已验证;HTTP 已能把确定性测试认证解析成 -当前 Membership-backed `UserActor`,构造 nominal `AuthenticatedInvocation`,并用 -closed body 与通用错误证明 caller 不能注入 trusted identity;该测试组合已通过唯一 -`ContextRuntime.resolve` 返回 tenant-safe ContextPackage。默认应用仍拒绝全部 -credential 并保持空包、零内容 I/O;显式 conformance 组合已证明 hostile -CandidateIndex 只能经同一 PostgreSQL 事务的 FORCE RLS、exact EffectiveScope 与 sealed -AuthorizationKernel 交付一个 synthetic exact-authorized Evidence/block。生产认证、durable -Principal/Agent grants、真实 Source ACL 与通用内容检索仍为 `NOT_ACTIVE`。Issue #17 -已激活唯一的 persistent no-op WorkerLease 子载体:server-minted lease 精确绑定 -Organization、job、registered ServicePrincipal binding、固定 workload/worker audience、 -过期时间与 nonce,并在 non-owner FORCE RLS 下只允许一次原子完成;该 bounded binding -不是完整 canonical `ServiceActor`,真实 ingestion、outbox 与 publication job 仍为 -`NOT_ACTIVE`。[Issue #18 的 ADR-0030](./docs/decisions/0030-bound-ticket-audiences.md) -也只激活 bounded signed-ticket separation proof:一个 synthetic -Provider read 与一个 synthetic channel no-op 共享 current `UserActor` identity chain 和 -key configuration,但使用不同 nominal types、signed domains、fixed operations 和 -provider/channel audiences。Agent/purpose 只从 matching -`AuthenticatedInvocation`/`TrustedDeliveryContext` 派生;各自的 type-aware deserializer -在创建 nominal ticket 前验证 signed namespace。两者均绑定 trusted -Organization/target、bounded expiry 与 V0 Policy Epoch;所有 mismatch 使用 generic -rejection 且 effect 为零。Production Provider、 -Sender/IM 与完整 M2 ActionPlane 仍为 `NOT_ACTIVE`。[Issue #19 的 -ADR-0031](./docs/decisions/0031-persist-authorized-context-run-lineage.md) 进一步激活 -当前 Acquire 的 digest-only authorized ContextRun 与 restricted delivered-empty -DecisionAudit;默认 production authentication、完整 Package/query retention 与通用 -observability redaction 仍未激活。整体计划见 [PLAN.md](./PLAN.md)。 - -## 开发命令 - -要求 Python 3.13 和 [uv](https://docs.astral.sh/uv/)。依赖版本由 -`uv.lock` 固定,仓库命令统一由 `make` 暴露: +[![CI](https://github.com/stone16/context-engine/actions/workflows/ci.yml/badge.svg)](https://github.com/stone16/context-engine/actions/workflows/ci.yml) +[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE) +[![Status](https://img.shields.io/badge/status-pre--release-orange.svg)](./STATUS.md) + +**A permission-aware context delivery engine.** Connect your team's knowledge +sources upstream; deliver **authorized, evidence-backed, budget-bounded** +ContextPackages to agents and chat bots downstream. + +[简体中文](./README.zh-CN.md) + +--- + +Most knowledge-base products answer *how do I store and search this?* Most RAG +toolchains answer *how do I find the nearest chunk?* ContextEngine exists +because the two questions that actually block shipping a trustworthy assistant +inside a company are different ones: + +## 1. What is this audience allowed to know, right now? + +Retrieval alone cannot answer that. In ContextEngine the index never returns +deliverable text — it returns a `CandidateRef`. Every candidate must pass +through a sealed `AuthorizationKernel` that performs exact authorization and +field projection before *anything* content-bearing happens. Hydration, +reranking, relevance models, and packaging all run on `AuthorizedProjection` +only. Every parent or neighbor expansion is re-authorized item by item. + +Source ACL evidence is explicitly classified as `Live`, `Mirrored`, or `Weak`. +`Weak` is only for sources that genuinely lack fine-grained ACLs — it is never +a fallback when a `Live` or `Mirrored` check fails. That case fails closed. + +## 2. Who keeps the knowledge base organized? + +Organization cost is the largest hidden cost of any team knowledge base. +ContextEngine assigns the automatable part to agents — semantic +deduplication, staleness marking, terminology capture — while humans keep the +audit. Every AI-produced annotation is proposed, confirmed, then published +atomically as a separate immutable `CurationSnapshot`. Published content +revisions are never mutated in place. + +## Project status + +> **Pre-release. Not usable in production, and not trying to look like it is.** + +ContextEngine is being built milestone by milestone, and each capability is +activated only when executable evidence proves it. Capabilities that have not +been proven are labeled `NOT_ACTIVE` rather than quietly stubbed — including in +the running service's own `/health` response. + +| Area | State | +|---|---| +| Real PostgreSQL 17 + pgvector harness, role separation, FORCE RLS | Active | +| Organization / Membership / `UserActor` tenant transaction | Active | +| Sealed `ContextRuntime.resolve` returning tenant-safe ContextPackage | Active | +| Exact-authorized Evidence tracer over a hostile candidate index | Active | +| OpenAPI v0 wire contract + generated TypeScript SDK + breaking-change gate | Active | +| Private File-backed bot delivery flow (deterministic twin) | Active | +| Autonomous File import dispatch + bounded expired-lease reclaim | Active | +| Production authentication (OAuth/JWT) | `NOT_ACTIVE` | +| Real source ACLs, general content retrieval, `Continue` / `OpenCitation` | `NOT_ACTIVE` | +| Live Feishu / Slack / Google Docs connectors, group chat | `NOT_ACTIVE` | + +**[→ Full capability ledger with per-issue evidence boundaries (STATUS.md)](./STATUS.md)** + +The roadmap and milestone exit criteria live in [PLAN.md](./PLAN.md). + +## Quick start + +### Prerequisites + +| Requirement | Where the version comes from | Why | +|---|---|---| +| [uv](https://docs.astral.sh/uv/) | — | Dependency resolution, pinned by `uv.lock` | +| [Python](https://www.python.org/) | `requires-python` in [`pyproject.toml`](./pyproject.toml) — `uv sync` provisions a matching interpreter for you | Engine, adapters, worker | +| [Node.js](https://nodejs.org/) | [`sdk/typescript/.node-version`](./sdk/typescript/.node-version) — `nvm use`, `fnm use`, and `asdf` read it automatically | TypeScript SDK, ActionPlane, BotDelivery | +| Docker (with Compose) | Service versions are pinned in [`compose.yaml`](./compose.yaml) | Real PostgreSQL + pgvector test harness | + +Every version above is declared in a checked-in file, so none of them are +repeated here — install the tool, and let it read the repository. + +### Install and verify ```bash -make install # uv sync --frozen -make build # 构建 wheel 和 sdist -make lint # Ruff -make typecheck # strict mypy -make test # 单元测试 -make catalog # 安全目录静态测试与校验 -make security-gate # 可执行 M0 安全否决门;要求先执行 make db-up -make smoke # API / worker 进程 smoke -make db-up # 启动 compose.yaml 固定的 PostgreSQL + pgvector 测试底座 -make db-down # 停止测试底座并保留 disposable data volume -make db-reset # 删除并重建该测试底座的 disposable data volume -make integration # 真实 PostgreSQL integration/security harness -make check # 全部门禁;要求先执行 make db-up +make install ``` -`make security-gate` 会发现并只执行注册的 M0 安全证据,核对真实 PostgreSQL -RLS inventory,并将机器可读的原始证据与四门 release report 写入被 Git 忽略的 -`.context-engine/security-gate/`。Security 是独立否决门;尚未进入 M0 评估范围的 -Reliability、Quality 与 Budget 明确记录为 `not-evaluated`,所以这份报告只会给出 -`m0SecurityDecision`,不会把安全门通过误写成可发布或可 promotion 的总体 PASS。 +`make install` syncs the locked Python environment **and** runs `npm ci` for the +three TypeScript workspaces (`sdk/`, `action_plane/`, `bot_delivery/`). Node is +not optional. -数据库底座首次启动时会在被 Git 忽略的 -`.context-engine/database.env` 生成随机凭据并将文件权限设为 `0600`;该文件是 -本地 migration、API Runtime、worker、security test 连接配置和该 checkout -独有 Compose project 身份的唯一实时来源,避免多个 worktree 或 checkout 共享 -容器、网络与数据卷。 -镜像及服务拓扑的版本真相位于 [`compose.yaml`](./compose.yaml),PostgreSQL 只绑定 -一个动态选择的 `127.0.0.1` host port。migration、runtime 与 worker 使用不同 -角色;runtime/security test 不会回退到 migration 或 bootstrap 凭据。 +Run the same gate CI runs, from a clean checkout: -从 clean checkout 运行与 CI 相同的数据库门禁: +```bash +make install && make db-up && make check && make db-down +``` + +### Run the API + +Bind an address explicitly so the example below is self-contained — run +`context-engine-api --help` for the defaults and the full flag set +(`--host`, `--port`, `--log-level`): ```bash -make install -make db-up -make check -make db-down +uv run context-engine-api --host 127.0.0.1 --port 8137 ``` -`make db-reset` 只删除当前 checkout 的 generated Compose project 所属的 -disposable PostgreSQL volume,然后从初始化脚本重建。它不会删除仓库内容,但会 -清除该本地测试数据库中的全部数据。 +```bash +curl http://127.0.0.1:8137/health +``` + +```json +{ + "status": "ready", + "service": "context-engine-api", + "version": "...", + "runtime_delivery": "NOT_ACTIVE" +} +``` -本地启动 API: +`runtime_delivery: NOT_ACTIVE` is expected and correct: the default application +rejects every credential and performs zero content I/O. The public wire contract +is `POST /v0/resolve`, frozen in [`openapi/v0/openapi.json`](./openapi/v0/openapi.json). + +### Run the worker + +The Supply worker is a separate process from the API, with one entry point and +four modes: ```bash -uv run context-engine-api +uv run context-engine-worker --test-mode # deterministic no-op lifecycle +uv run context-engine-worker --run-file-job # one exact signed File import job +uv run context-engine-worker --dispatch-file-once # one deterministic dispatch cycle +uv run context-engine-worker --dispatch-files # long-running dispatch loop ``` -监听地址和端口可通过 `context-engine-api --help` 中记录的参数覆盖;进程启动后 -在所配置地址请求 `/health`。 +`--test-mode` reports `job_behavior: NOT_ACTIVE`, meaning the default CLI has no +production signing key source, queue loop, or real ingestion handler configured. + +`--dispatch-files` is the production long-running entry: it polls on a +server-fixed one-second interval when there is no work, and exits on `SIGTERM` +or `SIGINT`. + +All dispatch modes read **only** a role-specific scheduler, worker URL, +WorkerLease signing key, and the server-side JSON root registry +(`CONTEXT_ENGINE_WORKER_FILE_ROOTS_JSON`). **A caller may not supply +Organization, Source, job, or token** — that is the point of the boundary. +Output is limited to `dispatched` / `no_work` / `refused`. -确定性运行 worker 的 no-op 测试生命周期: +Lease validation uses the worker's PostgreSQL clock, staying in the same time +domain as database-issued timestamps rather than depending on worker host clock +alignment. Unavailable worker infrastructure terminates dispatch instead of +continuing to claim and strand later jobs. File or content failures return +`refused` and continue scheduling only once that job is durably terminal-failed +or the current authority rejects that exact failure transition. + +Activation boundaries for File dispatch, reclaim, and delete execution are +recorded in [STATUS.md](./STATUS.md). + +### Development commands ```bash -uv run context-engine-worker --test-mode +make install # sync locked Python env + npm ci for the 3 TS workspaces +make build # build wheel and sdist +make lint # Ruff +make typecheck # strict mypy + TS typecheck +make test # Python unit tests +make catalog # static security catalog tests and validation +make smoke # API / worker process smoke suite +make db-up # start the pinned PostgreSQL 17 + pgvector harness +make db-down # stop it, preserving the disposable data volume +make db-reset # destroy and rebuild only that disposable volume +make integration # real-PostgreSQL integration/security harness +make security-gate # executable M0 security veto gate (needs make db-up) +make check # everything above (needs make db-up) +``` + +On first start the harness generates random credentials into a git-ignored, +mode-`0600` `.context-engine/database.env`. That file is the single live source +for local migration, runtime, worker, and security-test connection settings, and +it gives each checkout its own Compose project identity so parallel worktrees +never share containers, networks, or volumes. Image and topology versions are +pinned in [`compose.yaml`](./compose.yaml); PostgreSQL binds only one +dynamically chosen `127.0.0.1` port. Migration, runtime, and worker use distinct +roles, and runtime never falls back to migration or bootstrap credentials. + +`make security-gate` discovers and runs only registered M0 security evidence, +cross-checks the live PostgreSQL RLS inventory, and writes machine-readable raw +evidence plus an independent release-gate report to +`.context-engine/security-gate/`. Because Reliability, Quality, and Budget are +not yet in M0 scope, that report emits only an `m0SecurityDecision` and +explicitly records the others as `not-evaluated` — a passing security gate is +never reported as an overall release PASS. + +## Architecture + +### Three loops + +| Loop | Responsibility | Key objects | +|---|---|---| +| **Supply** | Sources → trusted candidates: fetch, parse, chunk, index, publish atomically | `ContextSource` / `ContextResource` / `ContextRevision` / `ContextFragment` | +| **Runtime** | Authenticated invocation → ContextPackage: candidates, authorized projection, relevance, packaging | `CandidateRef` / `AuthorizedProjection` / `ContextRun` / `ContextPackage` | +| **Learning** | Authorized-only traces → releasable improvements: golden sets, slice gates, versioned profiles | golden set / `ReleaseManifest` / `CurationSnapshot` | + +### The one public online contract + +```text +ContextRuntime.resolve(AuthenticatedInvocation, TrustedDeliveryContext, + Acquire | Continue | OpenCitation) + + → query understanding + dual recall (FTS + vector, RRF fusion) + → CandidateRef ← carries NO deliverable body + → AuthorizationKernel ← exact authorization + field projection + → AuthorizedProjection ← the first content-bearing value + → post-authorization hydration / rerank + + small-to-big expansion, each item re-authorized + → PackageBudget packing + sufficiency signal + → ContextPackage ← citations / purpose / TTL / asOf ``` -健康响应中的 `runtime_delivery: NOT_ACTIVE` 表示默认进程没有生产认证入口。worker -输出中的 `job_behavior: NOT_ACTIVE` 特指默认 CLI 尚未配置生产签名密钥来源、queue/job -loop;Issue #71 的 E2E 通过同一个 `context-engine-worker --run-file-job` 进程入口消费 -一个 exact signed FileImport WorkerLease。该入口要求显式 worker credential、已登记 -ServicePrincipal、logical File root 与 job binding,完成一个终态后退出,不引入第四个 -进程类型。 -loop 或真实 ingestion/publication handler;Issue #17 的 persistent no-op 应用 seam 与 -PostgreSQL authority 已激活并由 integration suite 调用。当前数据库测试证明 `compose.yaml` 固定的 -PostgreSQL/pgvector、 -角色隔离、迁移、连接池清理,以及 Organization + current Membership-backed -`UserActor` + `organization_record` 的事务级租户上下文、复合所有权和 FORCE RLS。 -它不声明 durable Principal/Agent grants、真实 ACL、生产级内容授权或生产 -ContextPackage 交付已经实现;注入的 conformance 组合证明当前 Membership 门禁、 -Issue #12 synthetic EffectiveScope 的 fail-closed 单调不扩张路径,以及 Issue #13 -hostile CandidateIndex 的 synthetic exact-authorized Evidence 路径;Issue #14 的 -paired Runtime/HTTP gate 进一步证明 cross-Organization、same-Organization denied -与 nonexistent Candidate 收敛为同一个 tenant-safe empty Package(不声明 timing -等价);Issue #15 进一步激活 Organization-level V0 Policy Epoch:内部专用最小权限 -non-owner Control 事务原子撤销 seeded access 并推进 epoch,sealed Acquire 在交付前复核当前 -epoch,因此相同 query、CandidateRef 与持久 Fragment 在第一次 post-revoke 请求中返回 -零 Evidence,且 Org B 不受影响。该测试能力不等于生产 grant/admin workflow。 -Issue #16 已把公开 Runtime wire 固定为 closed `Acquire | Continue | OpenCitation` -union,并在 server-owned `RuntimeCapabilityGate` 激活 M0 拒绝路径:已知但尚无真实 -carrier 的 Continue、OpenCitation、federated discovery 与 source-native authorization -在任何 Provider/index/source-content I/O 前分别返回通用 domain-level -`request_not_available` 或 `citation_not_available`;unknown variant 或 caller 自报 -capability 仍为通用 422。该激活只证明 deterministic refusal,不表示 continuation、 -citation、federated/source-native Provider 或 File publication 已实现。 -Issue #17 进一步加入 Organization-owned `service_principal` 与 `worker_noop_job`,以及 -显式 versioned keyring 的 canonical HMAC-SHA256 WorkerLease。Control issuer 使用数据库 -事务时间和 server-owned bounded TTL 签出租约;若旧 lease 已按数据库时间过期,可用新 -时间与 nonce 原子 takeover,恢复“事务已提交但 token 未交付”的 crash window,且旧 token -随后 effect 为零。worker 应用 seam 必须先以自身配置的 registered ServicePrincipal identity -与时钟验证签名、Organization、job 和时效,再打开数据库事务;durable receiver 固定为 -`supply.noop` + `context-engine-worker` + `noop.complete`,不接受 worker call 覆盖。 -worker 无直接两张 tenant table 的 `SELECT` 或 job `UPDATE` 权限;专用 non-login definer -function 是唯一 durable 读写边界,并在 FORCE RLS 下以数据库当前时间、key version、nonce -digest、issued-at/expiry 做一次条件更新。有效 lease 的 effect count -只能从 0 变为 1;wrong-org/job/audience、篡改、过期、禁用 ServicePrincipal、重放和 -并发 loser 均保持零新增 effect。该 bounded proof 不包含 Source/Resource/Revision、 -Policy Epoch、end-user delivery audience、idempotency/generation、outbox、File 或生产 -worker loop,也不发布或声称完整 canonical `ServiceActor`(其 source/allowed-set/Policy -Epoch 尚不存在),并将完整 `ACCEPT-008` fixture 保持 `future/fail_closed`。 - -Issue #18 加入 canonical HMAC-SHA256 `ContextAccessTicket` 与 `ActionTicket` -protocols;两者使用同一 validated `AuthenticatedInvocation` / -`TrustedDeliveryContext` identity chain 和 explicit versioned key configuration。 -Read protocol 固定 -`context-engine.context-access-ticket` / `CE-ContextAccessTicket` / -`synthetic.provider.read` 并派生 `context-read:`;action protocol 固定 -`context-engine.action-ticket` / `CE-ActionTicket` / -`synthetic.channel.noop` 并派生 `im-send:`。Issuer 与 handler 由 trusted -configuration 绑定一个 Organization/target;Agent/purpose 不接受裸字符串,token 也不 -提供公开 value constructor。两个独立 deserializer 在构造 nominal type 前验证签名、 -domain/type、fixed operation 与 schema;handler 再校验完整 identity、purpose、bounded -expiry、nonce 和 key version,并在两个独立 synthetic effect 前最后复核 Organization -V0 Policy Epoch。使用同一 key 的 cross-plane deserialize/pass、wrong -target/Organization、identity/audience mismatch、tamper、overlong/expired lifetime、 -authority failure 和 committed epoch bump 均返回一个 non-enumerating unavailable 结果, -rejected effect 为零。该 bounded proof 不激活 production Provider -discovery/projection、source credential、Sender/IM、`ActionPlane.prepare`/`perform`、 -payload/destination/approval/idempotency、DeliveryAttempt、durable one-shot/replay/ -concurrency、stored receipt 或 reconciliation;完整 `ACCEPT-012` carrier 在该 -Issue #18 激活中保持 `NOT_ACTIVE`。Issue #71 现已另行激活完整的私聊 File-backed -deterministic-twin carrier:独立 TypeScript Bot 进程只经 installed generated SDK -访问 Runtime,受控模型只消费一个当前 Package,placeholder 与 final/follow-up 分别 -通过 `ActionPlane.prepare` + `perform`,最终只保留 digest/ref 形式的 -`DeliveryReceipt` 与 restricted audit。Live Feishu、真实模型/Sender、群聊、补偿删除、 -Continue 与 MCP 仍为 `NOT_ACTIVE`。 - -Issue #19 为当前 authenticated Acquire 激活最小 durable lineage:每个成功空包或 -exact-authorized Package 都在返回前,于保留的 current-`UserActor` 事务内提交一条 -same-Organization、final、authorized-only `ContextRun`,公开 `decisionRef` 可经专用 -non-owner security-operator + exact Organization + 显式 trusted authorization seam -解析。空包另写仅含 Organization/run/decision、PolicySnapshot/epoch、 -`no_authorized_evidence` 类别与时间的 restricted `DecisionAudit`;不保存 raw query、 -denied Candidate/Fragment/Resource body、ID、名称、原因或数量。Query 只保留 -Organization-bound、versioned HMAC-SHA256 digest;Package 公开并持久化可验证的 -versioned canonical SHA-256 digest,retention mode 固定为 `digest_only`,不长期保存 -完整 Package。Unauthenticated/注入失败不是 ContextRun。该 bounded -`TRACE-REDACTION-012` 激活不扩称 logs/metrics/debug/evaluation/Learning、Continue/ -OpenCitation、feedback、完整 retrieval trace 或 production operator identity 已完成; -默认应用的 production authentication 仍为 reject-all。 - -### 当前 HTTP exact-authorized Evidence tracer - -`POST /v1/context:resolve` 的 conformance 组合可注入一个把 opaque credential -映射为 verified transport facts 的 authenticator、一个为已登记 Organization -签发 request-bound nominal proof 的 trusted authority,以及一个在单次 PostgreSQL -事务内校验 current Membership 并签发 lifetime-bound `UserActor` proof 的 authority; -该事务保持到 sealed Runtime 与 ContextPackage 构造完成。默认组合的有效 Acquire 返回 -`200 resolved` 与 evidence-free ContextPackage;显式 synthetic conformance 组合可在同一 -事务中把 content-free CandidateRef 依次经过 RLS locator、exact EffectiveScope、body -projection 与 sealed AuthorizationKernel,返回唯一 exact-authorized Evidence/block。 -无效 Membership 统一返回通用 401, -数据库 authority 不可用统一返回通用 503,且两者都不会调用内容系统。模块级默认应用的 -认证、Organization 与 Membership 三条生产 authority 均 reject-all;scope authority -默认显式返回七个 missing trusted operands,因此不会接受任何生产 credential,也不会 -产生可交付 scope。 - -请求体是 closed `kind` union:Acquire 允许 `need.query`、可选的有限 -`packageBudget` 和可选 `requestNarrowing`;Continue 允许 opaque -`continuationToken` 与可选更小的 `packageBudget`;OpenCitation 只允许 opaque -`citationOpenRef`。所有 ref/token 长度与集合数量均受 active profile 限制;每层 unknown field、重复 JSON key -以及重复 singleton security/transport header 都 fail closed;pre-auth body bytes 和 -JSON nesting 由 `adapters/http/transport.py` 的 versioned profile 限制。非法 -JSON/media type、 -认证失败和 closed-schema 失败分别使用 OpenAPI 记录的通用 400、401 和 422 响应, -不会回显 tenant、Principal、Membership 或注入字段。purpose 只来自服务端 route -policy;返回的 `organizationRef` 是新生成的 package-scoped opaque reference,不能作为 -后续请求的 trusted tenant input。空包的 blocks/evidence/gaps 均为空,coverage 为 -`no_authorized_evidence`;默认无候选路径的 Provider/index/source-content 调用均为零。内容 tracer 对 denied -same-Organization 与 cross-Organization 候选保持零 body bytes、零 Evidence refs 和零外部 -effect,并为 authorized block 保持一对一 Evidence 引用闭包与完整 lineage。确定性 -denied、cross-Organization 与 nonexistent probes 的 HTTP status、closed product -headers、Package body 与 Runtime domain outcome 在仅归一化 server-authored per-resolve -refs/timestamps 以及由它们必然派生的 `packageDigest` 后完全相同;每个未归一化 Package -仍先验证自己的 digest。响应不含 Resource 标识、名称、Candidate/denied 数量或拒绝 -原因。此门禁不测量或声明 timing equality。 - -确定性 authorities 与 real-PostgreSQL seeded composition 只属于测试组合。生产 OAuth/JWT、durable -Principal/Agent grant authority、真实 Source/Resource ACL、通用检索与 continuation -不属于这个已激活 tracer。Policy Epoch V0 本身也不激活 UI/外部 admin、 -access-mutation DecisionAudit、outbox、cleanup、真实 Continue/OpenCitation 或完整 -production WorkerLease/ticket carrier; -Issue #17 与 Issue #18 仅通过各自 ADR 单独激活前述 bounded proof。 -其中 Continue/OpenCitation 的 M0 通用拒绝已经激活,但真实 issuance/redemption carrier -仍保持 future;restricted in-process audit 只保留 `UNSUPPORTED_CAPABILITY` 类别, -Issue #19 的 durable DecisionAudit 仅覆盖 successful delivered-empty Acquire,不能被 -解释为 unavailable capability 或 Control access-mutation audit 已激活。 - -本次公开候选 bundle 包含实现权威、ADR、安全契约、PRD、Tech Spec -与四个公开参考仓的证据基线;经维护者批准并提交后,它们将与实现一同 -版本化。公开 prior art 仅限 Dify、RAGFlow、MaxKB、Onyx 的固定版本; -ContextEngine 的安全协议依据自身需求与威胁模型独立设计,零代码复制。 - -## 文档入口 - -- [Domain glossary](./CONTEXT.md):身份、安全、内容与生命周期术语的仓库 - 权威。 -- [Architecture Decision Record index](./docs/decisions/README.md):实现 - 边界、依赖方向、禁止捷径与重访触发器。 -- [Implementation Design v1.2](./docs/design/2026-07-18-context-engine-implementation-design.md): - 集成后的实现权威与里程碑边界。 -- [四个公开参考仓证据基线](./docs/research/2026-07-19-four-public-repositories-evidence.md): - 四仓优势、局限、clean-room 拆解与证据缺口。 -- [Threat Model](./docs/security/context-engine-threat-model.md):自有资产、 - 信任边界、威胁与 hard oracles。 -- [Program PRD](./docs/agents/prd-contextengine-implementation.md) 与 - [Implementation Epic Tech Spec](./docs/specs/2026-07-19-context-engine-implementation-epic.md): - 需求、100 条 user stories、contract shapes 与 work packages。 -- [D0 Baseline Candidate](./DESIGN-BASELINE.md):当前候选状态与尚未关闭的 - evidence gates。 - -独立 Supply worker 的确定性单周期 File dispatch 使用 -`context-engine-worker --dispatch-file-once`。生产长运行入口是 -`context-engine-worker --dispatch-files`;它以服务端固定的一秒间隔轮询无工作结果, -并在 `SIGTERM` / `SIGINT` 时结束。两种入口都只读取 role-specific scheduler、 -worker URL、WorkerLease signing key 和服务端 JSON root registry -(`CONTEXT_ENGINE_WORKER_FILE_ROOTS_JSON`);调用方不得提供 -Organization、Source、job 或 token。输出仅包含 `dispatched` / `no_work` / `refused`;Provider -polling、过期 lease reclaim、retry/dead-letter 与 delete execution 仍未激活。Worker -基础设施不可用会终止 dispatch,不会继续 claim 并滞留后续 job。 -文件/内容失败仅在该 job 已持久化为 terminal failed 或当前 authority 拒绝该精确 -failure transition 后返回 `refused` 并继续调度;failure recording 基础设施不可用仍会 -终止 dispatch。 -Lease 的立即验证使用 worker PostgreSQL 时钟,与数据库签发时间保持同一时间域, -不依赖 worker host clock 对齐。 - -当前除固定 commit 的四仓静态证据与仓库内设计拆解外,已有 -[`compose.yaml`](./compose.yaml) 固定的真实 PostgreSQL + pgvector 基础 harness, -以及首个 Organization-owned 代表表的 RLS 动态证据。 -完整 domain schema、ActorContext、filtered ANN 和飞书 capability 的动态证据仍未 -完成,因此不把这个证据切片扩称为完整产品授权能力。 - -## 为什么做这个 - -现有知识库产品回答的是「怎么存、怎么搜」;RAG 工具链回答的是「怎么找到最近的 -chunk」。都没有回答两个更难的问题: - -1. **这个 audience 此刻有权知道什么?** —— 索引只产生 - `CandidateRef`;sealed `ContextRuntime.resolve` 必须经 - `AuthorizationKernel` 执行 exact authorization 和字段投影,得到 - `AuthorizedProjection` 后,才能进入 Runtime 内的水合、精排、相关性模型和 - 装箱。BotDelivery 的生成模型只接收由当前 audience-bound ContextPackage - 派生的 `AuthorizedModelInput`。Live/Mirrored/Weak 三类 - SourceAclEvidence 各有明确语义,Weak 绝不是强 ACL 故障时的 fallback。 -2. **知识库由谁来组织?** —— Agent 承担可自动化的组织工作(语义去重、过期 - 标记、术语沉淀),用户负责 audit;所有 AI 产物先提案、经确认、再以独立的 - 不可变 `CurationSnapshot` 原子发布,绝不修改已发布的内容 Revision。 - -## 核心在线契约 - -`ContextRuntime.resolve(AuthenticatedInvocation, TrustedDeliveryContext, -Acquire | Continue | OpenCitation)` 是 Runtime 唯一公开能力,HTTP 是 V1 服务端 -ingress,TypeScript SDK 是 generated HTTP client;MCP 只在真实 caller 出现后 -激活。Continue 的 token 绑定 principal、one-shot 且累计预算;CitationOpenRef -本身不授权,每次打开都重新认证与授权。 - -IM 交付由受信 `BotDelivery` 深模块完成。它不在 wire body 自报 trusted -audience,而是通过认证 metadata 传递 opaque `DeliveryEvidenceRef`,由 ingress -兑换 `TrustedDeliveryContext` / `AudienceSnapshot`;群公开和提问者私有内容分别 -resolve,外部效果均通过 `ActionPlane.prepare` + `perform`。 - -## 三条硬底线(release veto,不是分数) - -- 无授权证据泄漏 = 0(Unauthorized Evidence = 0) -- 跨租户影响 = 0(wrong-Organization effect = 0) -- 缺失租户上下文一律 fail closed - -任何功能收益不能抵消其中任何一条的失败。每次发布按版本化 catalog 报告 -`PASS / FAIL / NOT_ACTIVE / NOT_APPLICABLE`,并把 capability coverage -单独列出;未激活能力不能冒充通过。 +This is the Runtime's **only** public capability. HTTP is the V1 server ingress; +the TypeScript SDK is a generated HTTP client, not a second transport. MCP stays +`NOT_ACTIVE` until a real caller exists. + +`Continue` uses a principal-bound, one-shot, budget-accumulating token. +`OpenCitation` uses an opaque `CitationOpenRef` that carries no authority of its +own — every open re-authenticates and re-authorizes. + +### Repository layout + +```text +engine/ The sealed core — no HTTP, no vendor SDKs + runtime/ resolve() orchestration, AuthorizationKernel, tickets, + budget, provenance, ContextRun, policy epoch + supply/ source → revision → fragment ingestion contracts + learning/ evaluation, candidates, sole release-promotion authority + control/ operator-facing access + file-import authority + persistence/ PostgreSQL connectivity, tenant context, RLS boundary +adapters/ Everything that touches the outside world + http/ FastAPI ingress, authentication, transport limits, routes + parsers/ format parsers (PDF / Markdown / Office) +applications/ Thin process entry points (~200 LOC total) + api.py `context-engine-api` + worker.py `context-engine-worker` +bot_delivery/ M2 trusted Bot process (TypeScript); generated-SDK caller +action_plane/ prepare() → one-shot ticket → exact external effect +sdk/typescript/ OpenAPI-generated HTTP client +eval/ golden sets, slice gates, judges, security catalogs +migrations/ Alembic migrations +tests/ unit / integration / catalog / process suites +docs/ design authority, 60 ADRs, threat model, PRD, research +CONTEXT.md domain glossary (terms only, no implementation) +PLAN.md vision, principles, roadmap, non-goals +``` + +Two structural facts worth noticing: + +- **Thin entry points, thick core.** `applications/` is roughly 200 lines. All + behavior lives in `engine/`, which is what makes "the production composition + root cannot substitute, skip, or wire a no-op `AuthorizationKernel`" an + enforceable property rather than a slogan. +- **Tests outweigh implementation ~3:1.** Roughly 21k lines under `engine/` + against roughly 68k lines under `tests/`. For a project whose central claim is + a security invariant, the executable evidence *is* the product. + +### What is pluggable, and what is not + +| Layer | Pluggable (seam) | Sealed (kernel) | +|---|---|---| +| Parsing | PDF / Markdown / Office parsers | — | +| Representation | embeddings, reranker, LLM | — | +| Storage | V1 fixed on PostgreSQL FTS + pgvector; only an in-Runtime candidate-injection test seam | authorization source of truth (PostgreSQL) | +| Ingress | connectors, HTTP server ingress, MCP once a real caller exists; the generated SDK is a client artifact | authenticated invocation + `TrustedDeliveryContext` construction | +| Governance | evaluation judge models | sealed `ContextRuntime` orchestration, `AuthorizationKernel`, `DecisionAudit`, budget, provenance | + +Portability is deliberately not promised before a second real backend exists. + +### Trusted delivery + +IM delivery is handled by `BotDelivery`, a trusted deep module that runs as its +own process from M2 and reaches the engine only through the generated HTTP SDK. +It does **not** declare its own audience in the wire body. It passes an opaque +`DeliveryEvidenceRef` in authenticated transport metadata; the ingress redeems +that for a `TrustedDeliveryContext` / `AudienceSnapshot`. Group permission +intersection is computed by the `AuthorizationKernel`, never by BotDelivery. + +A group-visible answer and an asker-private answer are two separate +audience-bound resolves — never one package split after the fact. All external +side effects go through `ActionPlane.prepare` then `ActionPlane.perform`, each +with its own org-scoped, audience- and payload-bound, one-shot `ActionTicket`. + +## The three hard invariants + +These are **release vetoes, not scores**: + +- Unauthorized Evidence leaked = **0** +- Wrong-Organization effect = **0** +- Missing tenant context = **fail closed, always** + +No feature win offsets a failure in any of them. Every release reports +`PASS / FAIL / NOT_ACTIVE / NOT_APPLICABLE` against a versioned catalog and +lists capability coverage separately, so an inactive capability can never +masquerade as a passing one. + +## Documentation + +| Document | What it gives you | +|---|---| +| [CONTEXT.md](./CONTEXT.md) | Domain glossary — the repository's authority on identity, security, content, and lifecycle terms | +| [PLAN.md](./PLAN.md) | Vision, non-negotiable design principles, roadmap, explicit non-goals | +| [STATUS.md](./STATUS.md) | Per-issue capability activation ledger and evidence boundaries | +| [ADR index](./docs/decisions/README.md) | 60 decision records: boundaries, dependency direction, forbidden shortcuts, revisit triggers | +| [Implementation Design](./docs/design/2026-07-18-context-engine-implementation-design.md) | The integrated implementation authority and milestone boundaries | +| [Threat Model](./docs/security/context-engine-threat-model.md) | Assets, trust boundaries, threats, hard oracles | +| [Program PRD](./docs/agents/prd-contextengine-implementation.md) · [Epic Tech Spec](./docs/specs/2026-07-19-context-engine-implementation-epic.md) | Requirements, 100 user stories, contract shapes, work packages | +| [Prior-art evidence baseline](./docs/research/2026-07-19-four-public-repositories-evidence.md) | Strengths, limits, clean-room breakdown, and evidence gaps of four public repositories | +| [D0 Baseline Candidate](./DESIGN-BASELINE.md) | Current candidate state and unclosed evidence gates | + +## Prior art + +The design draws on architectural study of four public open-source projects — +**Dify**, **RAGFlow**, **MaxKB**, and **Onyx** — limited strictly to observable +behavior, interface shape, test oracles, and product workflows. **Zero code was +copied.** Pinned versions and first-party links are recorded in the +[evidence baseline](./docs/research/2026-07-19-four-public-repositories-evidence.md). + +ContextEngine's security and multi-tenancy protocols are designed independently +from its own requirements and threat model. Research from outside this +repository may inform reasoning, but it is never cited as public provenance. + +## Contributing + +This project holds an unusually strict evidence bar — security invariants are +veto gates, and capabilities may not be activated without executable proof. +Please read [CONTRIBUTING.md](./CONTRIBUTING.md) before opening a pull request; +it covers the verification contract, the ADR workflow, and what "done" means +here. + +Issues and PRDs are tracked in +[GitHub Issues](https://github.com/stone16/context-engine/issues). ## License -TBD(设计阶段;在首个可运行版本前确定)。 +Copyright 2026 stone16. Licensed under the +[Apache License 2.0](./LICENSE) — which includes an explicit patent grant. +Attribution notices are in [NOTICE](./NOTICE). diff --git a/README.zh-CN.md b/README.zh-CN.md new file mode 100644 index 00000000..da609c5c --- /dev/null +++ b/README.zh-CN.md @@ -0,0 +1,321 @@ +# ContextEngine + +[![CI](https://github.com/stone16/context-engine/actions/workflows/ci.yml/badge.svg)](https://github.com/stone16/context-engine/actions/workflows/ci.yml) +[![License](https://img.shields.io/badge/license-Apache--2.0-blue.svg)](./LICENSE) +[![Status](https://img.shields.io/badge/status-pre--release-orange.svg)](./STATUS.md) + +**一个权限感知的上下文交付引擎。** 上游连接团队的知识源,下游把**经过授权、 +带证据、有预算**的 ContextPackage 交付给 agent 应用与 IM bot。 + +[English](./README.md) + +--- + +多数知识库产品回答的是「怎么存、怎么搜」,多数 RAG 工具链回答的是「怎么找到 +最近的 chunk」。ContextEngine 存在的理由是:真正卡住「在公司内部上线一个可信 +助手」的,是另外两个问题。 + +## 一、此刻这个 audience 有权知道什么? + +单靠检索回答不了这个问题。在 ContextEngine 里,索引永远不返回可交付正文——它 +只返回 `CandidateRef`。每一个候选都必须先经过 sealed `AuthorizationKernel` 完成 +精确授权与字段投影,**任何承载内容的动作才被允许发生**。水合、精排、相关性 +模型、装箱,全部只接受 `AuthorizedProjection`。每一次父级或邻居扩展都逐项 +重新授权。 + +源 ACL 证据被明确分为 `Live`、`Mirrored`、`Weak` 三类。`Weak` 只用于源本身确实 +缺乏细粒度 ACL 的场景,**它绝不是 `Live` / `Mirrored` 校验失败时的降级回退** +——那种情况一律 fail closed。 + +## 二、知识库由谁来组织? + +组织成本是任何团队知识库最大的隐性成本。ContextEngine 把其中可自动化的部分 +交给 agent——语义去重、过期标记、术语沉淀——而把 audit 留给人。所有 AI 产出的 +标注都要先提案、经确认,再作为独立的不可变 `CurationSnapshot` 原子发布。已发布 +的内容 Revision 永远不被就地修改。 + +## 项目状态 + +> **Pre-release。不可用于生产,也无意伪装成可以。** + +ContextEngine 按里程碑逐步构建,每一项能力只在**可执行的证据**证明之后才被 +激活。未经证明的能力一律标记为 `NOT_ACTIVE`,而不是悄悄留一个桩——包括在运行中 +服务自己的 `/health` 响应里。 + +| 领域 | 状态 | +|---|---| +| 真实 PostgreSQL 17 + pgvector 底座、角色隔离、FORCE RLS | 已激活 | +| Organization / Membership / `UserActor` 租户事务 | 已激活 | +| Sealed `ContextRuntime.resolve` 返回 tenant-safe ContextPackage | 已激活 | +| 对抗性候选索引下的 exact-authorized Evidence tracer | 已激活 | +| OpenAPI v0 wire 契约 + 生成式 TypeScript SDK + breaking-change 门禁 | 已激活 | +| 私聊 File-backed bot 交付闭环(确定性 twin) | 已激活 | +| 自主 File import dispatch + 有界的过期 lease reclaim | 已激活 | +| 生产认证(OAuth / JWT) | `NOT_ACTIVE` | +| 真实 Source ACL、通用内容检索、`Continue` / `OpenCitation` | `NOT_ACTIVE` | +| 飞书 / Slack / Google Docs 实连接器、群聊 | `NOT_ACTIVE` | + +**[→ 完整能力台账与逐 Issue 证据边界(STATUS.md)](./STATUS.md)** + +路线图与里程碑退出条件见 [PLAN.md](./PLAN.md)。 + +## 快速开始 + +### 前置依赖 + +| 依赖 | 版本来自哪里 | 用途 | +|---|---|---| +| [uv](https://docs.astral.sh/uv/) | — | 依赖解析,由 `uv.lock` 锁定 | +| [Python](https://www.python.org/) | [`pyproject.toml`](./pyproject.toml) 的 `requires-python`——`uv sync` 会自动装好匹配的解释器 | 引擎、adapters、worker | +| [Node.js](https://nodejs.org/) | [`sdk/typescript/.node-version`](./sdk/typescript/.node-version)——`nvm use`、`fnm use`、`asdf` 都会自动读取 | TypeScript SDK、ActionPlane、BotDelivery | +| Docker(含 Compose) | 服务版本固定在 [`compose.yaml`](./compose.yaml) | 真实 PostgreSQL + pgvector 测试底座 | + +上表每个版本都声明在已提交的文件里,所以这里一个都不重复——装好工具,让它自己 +读仓库。 + +### 安装与验证 + +```bash +make install +``` + +`make install` 除了同步锁定的 Python 环境,**还会对三个 TypeScript 工作区 +(`sdk/`、`action_plane/`、`bot_delivery/`)执行 `npm ci`**。Node 不是可选项。 + +从 clean checkout 运行与 CI 完全相同的门禁: + +```bash +make install && make db-up && make check && make db-down +``` + +### 启动 API + +显式指定监听地址,使下面的示例自成一体——默认值与完整参数集 +(`--host`、`--port`、`--log-level`)见 `context-engine-api --help`: + +```bash +uv run context-engine-api --host 127.0.0.1 --port 8137 +``` + +```bash +curl http://127.0.0.1:8137/health +``` + +```json +{ + "status": "ready", + "service": "context-engine-api", + "version": "...", + "runtime_delivery": "NOT_ACTIVE" +} +``` + +`runtime_delivery: NOT_ACTIVE` 是**预期且正确**的:默认应用拒绝一切 credential, +且不做任何内容 I/O。公开 wire 契约是 `POST /v0/resolve`,冻结在 +[`openapi/v0/openapi.json`](./openapi/v0/openapi.json)。 + +### 启动 worker + +Supply worker 是独立于 API 的进程,一个入口、四种模式: + +```bash +uv run context-engine-worker --test-mode # 确定性 no-op 生命周期 +uv run context-engine-worker --run-file-job # 一个精确签名的 File import job +uv run context-engine-worker --dispatch-file-once # 一次确定性 dispatch 周期 +uv run context-engine-worker --dispatch-files # 长运行 dispatch 循环 +``` + +`--test-mode` 输出 `job_behavior: NOT_ACTIVE`,表示默认 CLI 没有配置生产签名 +密钥来源、queue loop 或真实 ingestion handler。 + +`--dispatch-files` 是生产长运行入口:无工作结果时按**服务端固定的一秒间隔** +轮询,并在 `SIGTERM` / `SIGINT` 时结束。 + +所有 dispatch 模式**只**读取 role-specific scheduler、worker URL、WorkerLease +签名密钥,以及服务端 JSON root registry(`CONTEXT_ENGINE_WORKER_FILE_ROOTS_JSON`)。 +**调用方不得提供 Organization、Source、job 或 token**——这正是该边界的意义。 +输出仅限 `dispatched` / `no_work` / `refused`。 + +Lease 校验使用 worker 的 PostgreSQL 时钟,与数据库签发时间处于同一时间域, +不依赖 worker 宿主机时钟对齐。worker 基础设施不可用会**终止** dispatch,而不是 +继续 claim 并滞留后续 job。文件/内容失败仅在该 job 已持久化为 terminal failed, +或当前 authority 拒绝该精确 failure transition 之后,才返回 `refused` 并继续调度。 + +File dispatch、reclaim 与 delete execution 的激活边界记录在 +[STATUS.md](./STATUS.md)。 + +### 开发命令 + +```bash +make install # 同步锁定 Python 环境 + 三个 TS 工作区 npm ci +make build # 构建 wheel 与 sdist +make lint # Ruff +make typecheck # strict mypy + TS typecheck +make test # Python 单元测试 +make catalog # 安全目录静态测试与校验 +make smoke # API / worker 进程 smoke 套件 +make db-up # 启动固定版本的 PostgreSQL 17 + pgvector 底座 +make db-down # 停止底座,保留 disposable data volume +make db-reset # 只销毁并重建该 disposable volume +make integration # 真实 PostgreSQL integration/security harness +make security-gate # 可执行的 M0 安全否决门(需先 make db-up) +make check # 以上全部(需先 make db-up) +``` + +底座首次启动时,会在被 Git 忽略、权限 `0600` 的 `.context-engine/database.env` +生成随机凭据。该文件是本地 migration、runtime、worker 与安全测试连接配置的 +唯一实时来源,并为每个 checkout 生成独有的 Compose project 身份,使并行的 +worktree 之间永不共享容器、网络或数据卷。镜像与拓扑版本固定在 +[`compose.yaml`](./compose.yaml),PostgreSQL 只绑定一个动态选择的 `127.0.0.1` +端口。migration、runtime、worker 使用不同角色,且 runtime 绝不回退到 migration +或 bootstrap 凭据。 + +`make security-gate` 只发现并执行**已登记的** M0 安全证据,核对真实 PostgreSQL +的 RLS inventory,并把机器可读的原始证据与一份独立的 release-gate 报告写入 +`.context-engine/security-gate/`。由于 Reliability、Quality、Budget 尚未进入 M0 +范围,该报告只给出 `m0SecurityDecision`,并把其余三项明确记为 +`not-evaluated`——安全门通过**永远不会**被写成整体可发布的 PASS。 + +## 架构 + +### 三个循环 + +| 循环 | 职责 | 关键对象 | +|---|---|---| +| **Supply** | 源 → 可信候选:采集、解析、切分、索引、原子发布 | `ContextSource` / `ContextResource` / `ContextRevision` / `ContextFragment` | +| **Runtime** | 认证调用 → ContextPackage:候选、授权投影、相关性、装箱 | `CandidateRef` / `AuthorizedProjection` / `ContextRun` / `ContextPackage` | +| **Learning** | authorized-only trace → 可发布的改进:评测集、切片门禁、版本化 profile | golden set / `ReleaseManifest` / `CurationSnapshot` | + +### 唯一的在线公开契约 + +```text +ContextRuntime.resolve(AuthenticatedInvocation, TrustedDeliveryContext, + Acquire | Continue | OpenCitation) + + → 查询理解 + 双路召回(FTS + vector,RRF 融合) + → CandidateRef ← 不携带任何可交付正文 + → AuthorizationKernel ← 精确授权 + 字段投影 + → AuthorizedProjection ← 第一个承载内容的值 + → 授权后水合 / 精排 + + small-to-big 扩展,逐项重新授权 + → PackageBudget 装箱 + sufficiency 信号 + → ContextPackage ← citations / purpose / TTL / asOf +``` + +这是 Runtime **唯一**的公开能力。HTTP 是 V1 的服务端 ingress;TypeScript SDK 是 +生成式 HTTP client,不是第二条 transport。MCP 在真实 caller 出现前保持 +`NOT_ACTIVE`。 + +`Continue` 使用 principal-bound、one-shot 且累计预算的 token。`OpenCitation` +使用本身不携带任何授权能力的 opaque `CitationOpenRef`——每次打开都重新认证并 +重新授权。 + +### 仓库结构 + +```text +engine/ sealed 内核——不含 HTTP,不含厂商 SDK + runtime/ resolve() 编排、AuthorizationKernel、ticket、 + budget、provenance、ContextRun、policy epoch + supply/ 源 → revision → fragment 的摄取契约 + learning/ 评测、候选,以及唯一的发布提升权限 + control/ 面向 operator 的访问控制与 file-import 权限 + persistence/ PostgreSQL 连接、租户上下文、RLS 边界 +adapters/ 一切与外部世界接触的部分 + http/ FastAPI ingress、认证、传输限制、路由 + parsers/ 格式解析器(PDF / Markdown / Office) +applications/ 极薄的进程入口(合计约 200 行) + api.py `context-engine-api` + worker.py `context-engine-worker` +bot_delivery/ M2 受信 Bot 进程(TypeScript),generated-SDK 调用方 +action_plane/ prepare() → 一次性票据 → 精确外部效果 +sdk/typescript/ 由 OpenAPI 生成的 HTTP client +eval/ golden set、切片门禁、裁判、安全目录 +migrations/ Alembic 迁移 +tests/ unit / integration / catalog / process 套件 +docs/ 实现权威、60 篇 ADR、威胁模型、PRD、研究 +CONTEXT.md 领域术语表(只有术语,不含实现) +PLAN.md 愿景、原则、路线图、Non-goals +``` + +有两个结构事实值得注意: + +- **薄入口,厚内核。** `applications/` 只有约 200 行,全部行为都在 `engine/` + 里。这正是「生产 composition root 不能替换、跳过或装配 no-op + `AuthorizationKernel`」能成为一条**可强制执行的性质**、而不只是一句口号的原因。 +- **测试量约为实现量的 3 倍。** `engine/` 约 2.1 万行,`tests/` 约 6.8 万行。 + 对一个核心主张是安全不变量的项目来说,**可执行的证据本身就是产品**。 + +### 什么可插拔,什么不可 + +| 层 | 可插拔(seam) | 不可插拔(kernel) | +|---|---|---| +| 解析 | PDF / Markdown / Office parser | — | +| 表示 | embedding、reranker、LLM | — | +| 存储 | V1 固定 PostgreSQL FTS + pgvector;仅保留 Runtime 内候选注入的测试 seam | 授权真相库(PostgreSQL) | +| 接入 | connector、HTTP server ingress、真实 caller 出现后的 MCP;generated SDK 属于 client 产物 | 认证调用与 `TrustedDeliveryContext` 构造 | +| 治理 | 评测裁判模型 | sealed `ContextRuntime` 编排、`AuthorizationKernel`、`DecisionAudit`、budget、provenance | + +在第二个真实存储后端出现之前,**可移植性是被刻意不承诺的**。 + +### 受信交付 + +IM 交付由 `BotDelivery` 这个受信深模块完成。它从 M2 起作为独立进程部署,且只 +通过 generated HTTP SDK 访问引擎。它**不在 wire body 里自报 audience**,而是在 +认证 transport metadata 中传递一个 opaque `DeliveryEvidenceRef`,由 ingress +兑换为 `TrustedDeliveryContext` / `AudienceSnapshot`。群成员的权限交集由 +`AuthorizationKernel` 计算,绝不由 BotDelivery 计算。 + +群公开回答与提问者私有回答是**两次独立的、audience-bound 的 resolve**,绝不是 +把一个 Package 事后切分。所有外部副作用都经 `ActionPlane.prepare` 再 +`ActionPlane.perform`,每个效果使用各自 org-scoped、audience/payload-bound 的 +一次性 `ActionTicket`。 + +## 三条硬底线 + +这些是 **release veto,不是分数**: + +- 无授权证据泄漏 = **0** +- 跨租户影响 = **0** +- 缺失租户上下文 = **一律 fail closed** + +任何功能收益都不能抵消其中任何一条的失败。每次发布按版本化 catalog 报告 +`PASS / FAIL / NOT_ACTIVE / NOT_APPLICABLE`,并单独列出 capability coverage, +因此未激活的能力永远不可能冒充为通过。 + +## 文档 + +| 文档 | 提供什么 | +|---|---| +| [CONTEXT.md](./CONTEXT.md) | 领域术语表——身份、安全、内容与生命周期术语的仓库权威 | +| [PLAN.md](./PLAN.md) | 愿景、不可谈判的设计原则、路线图、明确的 Non-goals | +| [STATUS.md](./STATUS.md) | 逐 Issue 的能力激活台账与证据边界 | +| [ADR 索引](./docs/decisions/README.md) | 60 篇决策记录:边界、依赖方向、禁止捷径、重访触发器 | +| [实现设计](./docs/design/2026-07-18-context-engine-implementation-design.md) | 集成后的实现权威与里程碑边界 | +| [威胁模型](./docs/security/context-engine-threat-model.md) | 资产、信任边界、威胁与 hard oracles | +| [Program PRD](./docs/agents/prd-contextengine-implementation.md) · [Epic Tech Spec](./docs/specs/2026-07-19-context-engine-implementation-epic.md) | 需求、100 条 user story、contract shape、work package | +| [公开参照证据基线](./docs/research/2026-07-19-four-public-repositories-evidence.md) | 四个公开仓库的优势、局限、clean-room 拆解与证据缺口 | +| [D0 Baseline Candidate](./DESIGN-BASELINE.md) | 当前候选状态与尚未关闭的 evidence gate | + +## 参照与致谢 + +设计吸收了对四个公开开源项目——**Dify**、**RAGFlow**、**MaxKB**、**Onyx**——的 +架构研究,且严格限于可观察行为、interface 形状、测试 oracle 与产品工作流。 +**零代码复制。** 固定版本与一手链接记录在 +[证据基线](./docs/research/2026-07-19-four-public-repositories-evidence.md)。 + +ContextEngine 的安全与多租户协议依据自身 requirement 与威胁模型独立设计。 +仓库外的研究可以启发推理,但绝不作为公开 provenance 被引用。 + +## 参与贡献 + +本项目的证据门槛异常严格——安全不变量是否决门,能力未经可执行证明不得激活。 +提 PR 前请先阅读 [CONTRIBUTING.md](./CONTRIBUTING.md),其中说明了验证契约、 +ADR 流程,以及在这里「完成」意味着什么。 + +Issue 与 PRD 追踪于 +[GitHub Issues](https://github.com/stone16/context-engine/issues)。 + +## 许可证 + +Copyright 2026 stone16。基于 [Apache License 2.0](./LICENSE) 授权——包含明确的 +专利授权条款。归属声明见 [NOTICE](./NOTICE)。 diff --git a/STATUS.md b/STATUS.md new file mode 100644 index 00000000..dfe74176 --- /dev/null +++ b/STATUS.md @@ -0,0 +1,358 @@ +# Capability Status Ledger + +This file records **what ContextEngine has actually proven, and what it has +not**. It exists because "a demo ran" and "the authorization path is +implemented" are very different claims, and conflating them in a security +product is how trust gets destroyed. + +[← Back to README](./README.md) · [Roadmap and milestones](./PLAN.md) · +[ADR index](./docs/decisions/README.md) + +## How to read this file + +| Label | Meaning | +|---|---| +| **Active** | An executable, registered proof exists and runs in CI. The claim is bounded to exactly what that proof covers — never generalized. | +| **`NOT_ACTIVE`** | Deliberately not implemented or not proven yet. The running service reports this in its own responses (`/health`, worker output) rather than silently stubbing it. | + +Two rules govern every entry: + +1. **A bounded proof never grows into a general claim.** Where a proof uses a + synthetic fixture, a deterministic authority, or an injected test + composition, that is stated. It does not imply the production carrier works. +2. **The ADRs are authoritative.** This file is a navigational summary. When + this file and an ADR disagree, the ADR wins — and this file is the bug. + +## Global invariants + +These hold across every activation below and are release vetoes, not scores: + +- Unauthorized Evidence leaked = **0** +- Wrong-Organization effect = **0** +- Missing tenant context = **fail closed, always** + +Every release reports `PASS / FAIL / NOT_ACTIVE / NOT_APPLICABLE` against a +versioned catalog, with capability coverage listed separately, so an inactive +capability can never be reported as a passing one. + +## Currently `NOT_ACTIVE` + +The default application **rejects every credential and performs zero content +I/O**. The following are known, designed, and deliberately not active: + +| Capability | Note | +|---|---| +| Production authentication (OAuth / JWT) | Module-level default application is reject-all across all three production authorities (authentication, Organization, Membership) | +| Durable Principal / Agent grants | Scope authority returns seven missing trusted operands by default, so no deliverable scope can be produced | +| Real Source / Resource ACLs | Only synthetic conformance fixtures exist | +| General content retrieval | No production candidate path | +| `Continue` / `OpenCitation` carriers | The M0 *refusal* path is active; real issuance and redemption are not | +| Federated discovery, source-native authorization | Deterministic refusal only | +| Live Feishu / Slack / Google Docs connectors | See [PLAN.md](./PLAN.md) milestones M4 / M6 / M7 | +| Group-chat delivery, compensating deletes | M5 | +| MCP ingress | Held `NOT_ACTIVE` until a real caller exists | +| Worker dead-letter transition / operator requeue | ADR-0060 adds bounded reclaim only; generation four is left untouched after expiry | +| Provider polling, delete execution beyond ADR-0057 | See the File Provider ADRs for exact boundaries | +| Streaming delivery | Explicit V1 non-goal — placeholder + edit instead | +| Answer generation inside the engine | Permanent non-goal — generation always lives above the engine boundary | + +## Activation ledger + +Each accepted ADR below activated a bounded, separately proven capability. +Follow the ADR for its exact evidence boundary. + +### Security foundation and the sealed Runtime + +| ADR | Activates | +|---|---| +| [0030](./docs/decisions/0030-bound-ticket-audiences.md) | Bound the first ticket audiences to synthetic effects | +| [0031](./docs/decisions/0031-persist-authorized-context-run-lineage.md) | Persist authorized-only ContextRun lineage before delivery | +| [0032](./docs/decisions/0032-bind-materialized-fields-to-membership-projection-rights.md) | Bind materialized fields to current Membership projection rights | +| [0033](./docs/decisions/0033-promote-organization-releases-through-one-learning-owner.md) | Promote Organization releases through one Learning owner | +| [0034](./docs/decisions/0034-execute-the-m0-security-veto-from-registered-evidence.md) | Execute the M0 security veto from registered evidence | + +### File Provider (Provider #1) — Supply loop + +| ADR | Activates | +|---|---| +| [0035](./docs/decisions/0035-register-file-sources-through-context-control.md) | Register File sources through one trusted ContextControl transaction | +| [0036](./docs/decisions/0036-compile-narrow-markdown-deterministically.md) | Compile the first Markdown shape from canonical bytes | +| [0037](./docs/decisions/0037-publish-first-file-through-exact-worker-lease.md) | Publish the first File through an exact WorkerLease | +| [0038](./docs/decisions/0038-compile-and-publish-structural-markdown.md) | Compile and publish structural Markdown units | +| [0039](./docs/decisions/0039-deduplicate-unchanged-file-acquisitions.md) | Deduplicate unchanged File acquisitions before publication | +| [0040](./docs/decisions/0040-stage-and-atomically-activate-file-replacements.md) | Stage and atomically activate File replacements | +| [0041](./docs/decisions/0041-recover-file-publication-by-durable-boundary.md) | Recover File publication by durable boundary | +| [0042](./docs/decisions/0042-tombstone-file-resources-before-cleanup.md) | Tombstone File Resources before cleanup | +| [0043](./docs/decisions/0043-separate-file-acquisition-progress-from-publication-progress.md) | Separate File acquisition progress from publication progress | +| [0044](./docs/decisions/0044-disable-file-sources-before-cleanup.md) | Disable File sources before cleanup | +| [0054](./docs/decisions/0054-acknowledge-file-change-pages-before-cursor-advance.md) | Acknowledge File change pages before cursor advance | +| [0055](./docs/decisions/0055-schedule-accepted-file-observations-explicitly.md) | Schedule accepted File observations explicitly | +| [0056](./docs/decisions/0056-detect-file-deletions-without-tombstone-authority.md) | Detect File deletions without tombstone authority | +| [0057](./docs/decisions/0057-execute-current-file-deletes-through-tombstone-authority.md) | Execute current File deletes through tombstone authority | +| [0058](./docs/decisions/0058-schedule-only-upserts-from-mixed-file-pages.md) | Schedule only upserts from mixed File pages | +| [0059](./docs/decisions/0059-dispatch-scheduled-file-imports-through-exact-leases.md) | Dispatch scheduled File imports through exact leases | +| [0060](./docs/decisions/0060-reclaim-expired-file-imports-with-bounded-retries.md) | Reclaim expired File imports with bounded retries | + +### Wire contract, SDK, and trusted delivery + +| ADR | Activates | +|---|---| +| [0045](./docs/decisions/0045-redeem-private-delivery-evidence-at-ingress.md) | Redeem private delivery evidence at ingress | +| [0046](./docs/decisions/0046-bind-egress-to-one-exact-package-hop.md) | Bind egress to one exact Package hop | +| [0047](./docs/decisions/0047-freeze-openapi-v0-through-one-runtime-path.md) | Freeze OpenAPI v0 through one sealed Runtime path | +| [0048](./docs/decisions/0048-generate-typescript-sdk-behind-a-closed-facade.md) | Generate the TypeScript SDK behind a closed facade | +| [0049](./docs/decisions/0049-prepare-one-exact-private-effect.md) | Prepare one exact private effect before Sender | +| [0050](./docs/decisions/0050-perform-one-exact-private-effect.md) | Perform one exact private effect under one provider attempt | +| [0051](./docs/decisions/0051-reauthorize-opaque-citation-opens.md) | Reauthorize every opaque citation open | +| [0052](./docs/decisions/0052-gate-model-generation-by-package.md) | Gate model generation by one authorized Package | +| [0053](./docs/decisions/0053-compose-one-private-bot-delivery.md) | Compose one private File-backed Bot delivery | + +The complete, current list of accepted decisions — including everything before +ADR-0030 — is the [ADR index](./docs/decisions/README.md). + +## Boundary notes + +These record the exact scope of the foundational M0 proofs, including what each +one explicitly does **not** claim. + +### Database and tenant isolation + +The database harness proves the `compose.yaml`-pinned PostgreSQL 17 + pgvector +topology, role isolation, migrations, and connection-pool cleanup, plus a +transaction-scoped tenant context built from Organization + current +Membership-backed `UserActor` + `organization_record`, with composite ownership +and FORCE RLS. + +It does **not** claim durable Principal/Agent grants, real ACLs, +production-grade content authorization, or production ContextPackage delivery. + +### Issue #12 — fail-closed EffectiveScope + +An injected conformance composition proves the current Membership gate and a +synthetic `EffectiveScope` on a fail-closed, monotonically non-expanding path. + +### Issue #13 — hostile candidate index + +A synthetic exact-authorized Evidence path proves that a hostile +`CandidateIndex` can deliver exactly one synthetic authorized Evidence block, +and only by passing through FORCE RLS in the same PostgreSQL transaction, an +exact `EffectiveScope`, and the sealed `AuthorizationKernel`. + +### Issue #14 — convergent empty packages + +A paired Runtime/HTTP gate proves that cross-Organization, same-Organization +denied, and nonexistent-Candidate probes all converge on the same tenant-safe +empty Package. + +HTTP status, closed product headers, Package body, and Runtime domain outcome +are identical after normalizing only server-authored per-resolve refs and +timestamps plus the `packageDigest` necessarily derived from them; each +un-normalized Package still verifies its own digest first. + +**This gate does not measure or claim timing equivalence.** + +### Issue #15 — V0 Policy Epoch + +An internal, least-privilege, non-owner Control transaction atomically revokes +seeded access and advances the Organization-level V0 Policy Epoch. A sealed +`Acquire` re-checks the current epoch before delivery, so an identical query, +`CandidateRef`, and persisted Fragment return zero Evidence on the first +post-revocation request, with Organization B unaffected. + +This test capability is **not** a production grant or admin workflow. Policy +Epoch V0 does not activate UI or external admin, access-mutation +`DecisionAudit`, outbox, cleanup, or real `Continue` / `OpenCitation`. + +### Issue #16 — closed capability gate + +The public Runtime wire is fixed to the closed `Acquire | Continue | +OpenCitation` union. A server-owned `RuntimeCapabilityGate` activates the M0 +rejection path: known-but-uncarried `Continue`, `OpenCitation`, federated +discovery, and source-native authorization each return a generic domain-level +`request_not_available` or `citation_not_available` **before any +Provider/index/source-content I/O**. Unknown variants or caller-declared +capability remain a generic 422. + +This proves deterministic refusal only. It does not mean continuation, +citation, federated or source-native Providers, or File publication are +implemented. The restricted in-process audit retains only the +`UNSUPPORTED_CAPABILITY` category. + +### Issue #17 — WorkerLease (persistent no-op sub-carrier) + +Adds Organization-owned `service_principal` and `worker_noop_job` tables plus a +canonical HMAC-SHA256 WorkerLease with an explicit versioned keyring. + +The Control issuer signs leases using database transaction time and a +server-owned bounded TTL. If a prior lease has expired by database time, a new +time and nonce allow atomic takeover — recovering the "transaction committed +but token never delivered" crash window, after which the old token has zero +effect. The worker seam must verify signature, Organization, job, and validity +against its own configured registered ServicePrincipal identity and clock +*before* opening a database transaction. The durable receiver is fixed to +`supply.noop` + `context-engine-worker` + `noop.complete` and accepts no +caller override. + +The worker holds no direct `SELECT` on the two tenant tables and no `UPDATE` on +the job. A dedicated non-login definer function is the only durable read/write +boundary, performing one conditional update under FORCE RLS keyed on database +current time, key version, nonce digest, and issued-at/expiry. A valid lease's +effect count can only go from 0 to 1; wrong-org/job/audience, tampering, +expiry, disabled ServicePrincipal, replay, and concurrent losers all keep zero +additional effect. + +This bounded proof excludes Source/Resource/Revision, Policy Epoch, end-user +delivery audience, idempotency/generation, outbox, and the production worker +loop. It does **not** publish or claim a complete canonical `ServiceActor` — +its source, allowed-set, and Policy Epoch do not exist yet — and keeps the full +`ACCEPT-008` fixture at `future/fail_closed`. + +### Issue #18 — separated ticket planes (ADR-0030) + +Adds canonical HMAC-SHA256 `ContextAccessTicket` and `ActionTicket` protocols. +Both use the same validated `AuthenticatedInvocation` / `TrustedDeliveryContext` +identity chain and explicit versioned key configuration, but differ in every +other dimension: + +| | Read protocol | Action protocol | +|---|---|---| +| Domain | `context-engine.context-access-ticket` | `context-engine.action-ticket` | +| Signed prefix | `CE-ContextAccessTicket` | `CE-ActionTicket` | +| Fixed operation | `synthetic.provider.read` | `synthetic.channel.noop` | +| Derived audience | `context-read:` | `im-send:` | + +Issuer and handler are bound by trusted configuration to one +Organization/target. Agent and purpose accept no bare strings, and tokens +expose no public value constructor. Two independent deserializers validate +signature, domain/type, fixed operation, and schema before constructing a +nominal type; the handler then checks full identity, purpose, bounded expiry, +nonce, and key version, and re-checks the Organization V0 Policy Epoch last, +before two independent synthetic effects. + +Cross-plane deserialize/pass using the same key, wrong target/Organization, +identity or audience mismatch, tampering, overlong or expired lifetime, +authority failure, and a committed epoch bump all return one non-enumerating +unavailable result with **zero** rejected effect. + +This bounded proof does not activate production Provider discovery or +projection, source credentials, Sender/IM, `ActionPlane.prepare`/`perform`, +payload/destination/approval/idempotency, `DeliveryAttempt`, durable +one-shot/replay/concurrency, stored receipts, or reconciliation. The full +`ACCEPT-012` carrier remains `NOT_ACTIVE` under this activation. + +### Issue #19 — authorized-only ContextRun lineage (ADR-0031) + +Every successful empty or exact-authorized Package now commits, before +returning and inside the retained current-`UserActor` transaction, one +same-Organization, final, authorized-only `ContextRun`. Its public +`decisionRef` resolves only through a dedicated non-owner security operator, +an exact Organization, and an explicit trusted authorization seam. + +An empty package additionally writes a restricted `DecisionAudit` containing +only Organization/run/decision, PolicySnapshot/epoch, the +`no_authorized_evidence` category, and time. It stores **no** raw query, and no +denied Candidate/Fragment/Resource body, ID, name, reason, or count. + +Queries are retained only as an Organization-bound, versioned HMAC-SHA256 +digest. Packages expose and persist a verifiable versioned canonical SHA-256 +digest, with retention mode fixed to `digest_only` — full Packages are not +retained. Unauthenticated or injection failures are not a ContextRun. + +This bounded `TRACE-REDACTION-012` activation does not extend to logs, metrics, +debug, evaluation, or Learning; nor to `Continue` / `OpenCitation`, feedback, +full retrieval traces, or production operator identity. The default +application's production authentication remains reject-all. + +### Issue #71 — private File-backed delivery twin + +Activates a complete private-chat, File-backed, deterministic-twin carrier: an +independent TypeScript Bot process reaches the Runtime **only** through the +installed generated SDK; the controlled model consumes exactly one current +Package; placeholder and final/follow-up messages each go through +`ActionPlane.prepare` + `perform`; and only digest/ref-form `DeliveryReceipt` +plus a restricted audit are retained. + +A bounded File import job runs through the same `context-engine-worker +--run-file-job` process entry point, consuming one exact signed FileImport +WorkerLease. It requires an explicit worker credential, a registered +ServicePrincipal, a logical File root, and a job binding; it exits after one +terminal state and introduces no fourth process type. + +Live Feishu, real models and Senders, group chat, compensating deletes, +`Continue`, and MCP all remain `NOT_ACTIVE`. + +### HTTP exact-authorized Evidence tracer + +The conformance composition for the resolve route can inject an authenticator +that maps an opaque credential to verified transport facts, a trusted authority +that issues request-bound nominal proof for a registered Organization, and an +authority that validates current Membership inside a single PostgreSQL +transaction and issues a lifetime-bound `UserActor` proof. That transaction is +held open until the sealed Runtime and ContextPackage construction complete. + +**No `200` is reachable from the production default.** `create_app()` selects +`RejectingAuthenticator`, `RejectingOrganizationAuthority`, and +`RejectingMembershipAuthority` whenever no authorities are injected, so every +credential is rejected before an `Acquire` can reach a successful response. Do +not try to reproduce the results below against a default-built application — +they exist only under an explicitly injected composition. + +Within that injected conformance composition there are two variants: + +| Variant | Result | +|---|---| +| No candidate injection | A valid `Acquire` returns `200 resolved` with an evidence-free ContextPackage | +| Explicit synthetic candidate injection | A content-free `CandidateRef` passes through the RLS locator, exact `EffectiveScope`, body projection, and the sealed `AuthorizationKernel` in that same transaction, returning exactly one authorized Evidence block | + +Invalid Membership returns a generic 401; an unavailable database authority +returns a generic 503. **Neither calls any content system.** + +**Request shape.** The body is a closed `kind` union. `Acquire` permits +`need.query`, an optional bounded `packageBudget`, and optional +`requestNarrowing`. `Continue` permits an opaque `continuationToken` and an +optionally smaller `packageBudget`. `OpenCitation` permits only an opaque +`citationOpenRef`. All ref/token lengths and collection sizes are limited by the +active profile. Unknown fields at every level, duplicate JSON keys, and +duplicate singleton security/transport headers all fail closed; pre-auth body +bytes and JSON nesting are limited by the versioned profile in +[`adapters/http/transport.py`](./adapters/http/transport.py). + +**Response shape.** Malformed JSON or media type, authentication failure, and +closed-schema failure use the generic 400, 401, and 422 responses recorded in +OpenAPI, and never echo tenant, Principal, Membership, or injected fields. +Purpose comes only from server-side route policy. The returned +`organizationRef` is a freshly generated package-scoped opaque reference and +cannot be used as trusted tenant input on a later request. An empty package has +empty blocks, evidence, and gaps, with coverage `no_authorized_evidence`, and +makes zero Provider/index/source-content calls. + +The content tracer holds zero body bytes, zero Evidence refs, and zero external +effects for denied same-Organization and cross-Organization candidates, while +maintaining a one-to-one Evidence reference closure and full lineage for +authorized blocks. + +**Deterministic authorities and the real-PostgreSQL seeded composition belong to +the test composition only.** Production OAuth/JWT, durable Principal/Agent grant +authority, real Source/Resource ACLs, general retrieval, and continuation are +not part of this activated tracer. + +## Evidence and reporting + +`make security-gate` discovers and executes only registered M0 security +evidence, cross-checks the live PostgreSQL RLS inventory, and writes +machine-readable raw evidence plus an independent release-gate report into the +git-ignored `.context-engine/security-gate/` directory. CI retains both as build +artifacts. + +Security is an independent veto gate. Reliability, Quality, and Budget are not +yet in M0 scope and are explicitly recorded as `not-evaluated`, so the report +emits only an `m0SecurityDecision` — a passing security gate is never reported +as an overall release or promotion PASS. + +Beyond the pinned-commit evidence for the four public reference repositories and +the in-repository design breakdown, the dynamic evidence that exists today is +the `compose.yaml`-pinned PostgreSQL + pgvector harness and RLS evidence for the +first Organization-owned representative table. Dynamic evidence for the complete +domain schema, ActorContext, filtered ANN, and Feishu capability is still +outstanding — which is why this evidence slice is not described as a complete +product authorization capability. diff --git a/action_plane/typescript/LICENSE b/action_plane/typescript/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/action_plane/typescript/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/action_plane/typescript/NOTICE b/action_plane/typescript/NOTICE new file mode 100644 index 00000000..701a2605 --- /dev/null +++ b/action_plane/typescript/NOTICE @@ -0,0 +1,6 @@ +ContextEngine +Copyright 2026 stone16 + +Licensed under the Apache License, Version 2.0 (the "License"). +You may obtain a copy of the License in the LICENSE file distributed with this +work, or at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/action_plane/typescript/package-lock.json b/action_plane/typescript/package-lock.json index ddf1dabb..26e47329 100644 --- a/action_plane/typescript/package-lock.json +++ b/action_plane/typescript/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "@context-engine/action-plane", "version": "0.0.0-m2-perform", - "license": "UNLICENSED", + "license": "Apache-2.0", "dependencies": { "canonicalize": "3.0.0" }, diff --git a/action_plane/typescript/package.json b/action_plane/typescript/package.json index 51622c1d..df1dee9a 100644 --- a/action_plane/typescript/package.json +++ b/action_plane/typescript/package.json @@ -4,7 +4,7 @@ "description": "Trusted private ActionPlane prepare and perform module", "type": "module", "private": true, - "license": "UNLICENSED", + "license": "Apache-2.0", "engines": { "node": "22.12.0", "npm": "10.9.0" @@ -20,6 +20,8 @@ "files": [ "dist", "README.md", + "LICENSE", + "NOTICE", "THIRD_PARTY_NOTICES.md" ], "scripts": { diff --git a/bot_delivery/typescript/LICENSE b/bot_delivery/typescript/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/bot_delivery/typescript/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/bot_delivery/typescript/NOTICE b/bot_delivery/typescript/NOTICE new file mode 100644 index 00000000..701a2605 --- /dev/null +++ b/bot_delivery/typescript/NOTICE @@ -0,0 +1,6 @@ +ContextEngine +Copyright 2026 stone16 + +Licensed under the Apache License, Version 2.0 (the "License"). +You may obtain a copy of the License in the LICENSE file distributed with this +work, or at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/bot_delivery/typescript/package-lock.json b/bot_delivery/typescript/package-lock.json index 63bb9e09..edc184eb 100644 --- a/bot_delivery/typescript/package-lock.json +++ b/bot_delivery/typescript/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "@context-engine/bot-delivery", "version": "0.0.0-m2-private-flow", - "license": "UNLICENSED", + "license": "Apache-2.0", "dependencies": { "canonicalize": "3.0.0", "pg": "8.22.0" @@ -35,7 +35,7 @@ "name": "@context-engine/action-plane", "version": "0.0.0-m2-perform", "dev": true, - "license": "UNLICENSED", + "license": "Apache-2.0", "dependencies": { "canonicalize": "3.0.0" }, @@ -54,7 +54,7 @@ "name": "@context-engine/resolve-sdk", "version": "0.0.0-v0", "dev": true, - "license": "UNLICENSED", + "license": "Apache-2.0", "devDependencies": { "@hey-api/openapi-ts": "0.95.0", "@types/node": "22.10.2", diff --git a/bot_delivery/typescript/package.json b/bot_delivery/typescript/package.json index fd2f1829..0be79d9e 100644 --- a/bot_delivery/typescript/package.json +++ b/bot_delivery/typescript/package.json @@ -4,7 +4,7 @@ "description": "Trusted private File-backed BotDelivery application module", "type": "module", "private": true, - "license": "UNLICENSED", + "license": "Apache-2.0", "engines": { "node": "22.12.0", "npm": "10.9.0" @@ -23,6 +23,8 @@ "files": [ "dist", "README.md", + "LICENSE", + "NOTICE", "THIRD_PARTY_NOTICES.md" ], "scripts": { diff --git a/pyproject.toml b/pyproject.toml index 2cdd19b6..36eff2a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,6 +7,8 @@ name = "context-engine" version = "0.1.0" description = "Permission-aware context delivery engine" readme = "README.md" +license = "Apache-2.0" +license-files = ["LICENSE", "NOTICE"] requires-python = ">=3.13,<3.14" dependencies = [ "alembic>=1.16,<1.17", diff --git a/sdk/typescript/LICENSE b/sdk/typescript/LICENSE new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/sdk/typescript/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/sdk/typescript/NOTICE b/sdk/typescript/NOTICE new file mode 100644 index 00000000..701a2605 --- /dev/null +++ b/sdk/typescript/NOTICE @@ -0,0 +1,6 @@ +ContextEngine +Copyright 2026 stone16 + +Licensed under the Apache License, Version 2.0 (the "License"). +You may obtain a copy of the License in the LICENSE file distributed with this +work, or at http://www.apache.org/licenses/LICENSE-2.0 diff --git a/sdk/typescript/package-lock.json b/sdk/typescript/package-lock.json index 6e77dd65..99d1476b 100644 --- a/sdk/typescript/package-lock.json +++ b/sdk/typescript/package-lock.json @@ -7,7 +7,7 @@ "": { "name": "@context-engine/resolve-sdk", "version": "0.0.0-v0", - "license": "UNLICENSED", + "license": "Apache-2.0", "devDependencies": { "@hey-api/openapi-ts": "0.95.0", "@types/node": "22.10.2", diff --git a/sdk/typescript/package.json b/sdk/typescript/package.json index e6a5f577..4a6a1ba9 100644 --- a/sdk/typescript/package.json +++ b/sdk/typescript/package.json @@ -4,7 +4,7 @@ "description": "Generated TypeScript client for the frozen ContextEngine resolve v0 contract", "type": "module", "private": true, - "license": "UNLICENSED", + "license": "Apache-2.0", "repository": { "type": "git", "url": "git+https://github.com/stone16/context-engine.git", @@ -27,6 +27,8 @@ "contract/openapi-v0.sha256", "dist", "README.md", + "LICENSE", + "NOTICE", "THIRD_PARTY_NOTICES.md" ], "scripts": {