Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
501821d
test(tool-capability): define durable lifecycle ledger hostile cases
seonghobae Sep 9, 2026
a79e798
feat(tool-capability): persist lifecycle evidence with CAS
seonghobae Sep 9, 2026
ed89403
test(tool-capability): isolate transition-id semantic conflict
seonghobae Sep 9, 2026
d78aa8f
test(tool-capability): cover durable-ledger corruption branches
seonghobae Sep 9, 2026
988b077
feat(tool-capability): revalidate activation evidence before lifecycl…
seonghobae Sep 9, 2026
1fcdf6a
test(tool-capability): enforce fresh activation evidence boundary
seonghobae Sep 9, 2026
df56960
feat(tool-capability): bridge lifecycle activation to live owner evid…
seonghobae Sep 9, 2026
54aa141
test(tool-capability): cover live activation evidence revalidation
seonghobae Sep 9, 2026
c837025
test(tool-capability): expose activation replay revalidation bug
seonghobae Sep 9, 2026
ef675b4
fix(tool-capability): replay committed activation before live evidenc…
seonghobae Sep 9, 2026
4ee509f
test(tool-capability): cover transactional idempotency races
seonghobae Sep 9, 2026
48da6aa
test(tool-capability): expose replay integrity gaps
seonghobae Sep 9, 2026
2d7ea9a
fix(tool-capability): verify and replay immutable lifecycle evidence
seonghobae Sep 9, 2026
2594cfd
test(tool-capability): cover missing replay audit tail
seonghobae Sep 9, 2026
67300ff
test(tool-capability): cover transactional replay integrity
seonghobae Sep 9, 2026
16b3b0f
test(tool-capability): expose transaction-time replay digest race
seonghobae Sep 9, 2026
c373189
fix(tool-capability): verify replay after serialized transaction
seonghobae Sep 9, 2026
10630aa
test(tool-capability): expose O(n) current projection scan
seonghobae Sep 9, 2026
0a49f5b
fix(tool-capability): keep current projection O(1)
seonghobae Sep 9, 2026
3225766
test(tool-capability): cover missing projection tail
seonghobae Sep 9, 2026
5c61dc1
test(tool-capability): close replay coverage gaps
seonghobae Sep 9, 2026
fbe9d01
test(tool-capability): expose activation evidence replay race
seonghobae Sep 9, 2026
74b5555
fix(tool-capability): replay exact activation after evidence race
seonghobae Sep 9, 2026
4f1fb30
docs(context-map): bind lifecycle evidence to Noema boundaries
seonghobae Sep 9, 2026
7838afc
docs(adr): define durable external-extension lifecycle evidence
seonghobae Sep 9, 2026
fa69d84
test(tool-capability): reject forged lifecycle head authority
seonghobae Sep 9, 2026
5c4a323
docs(test): cover durable lifecycle evidence races and recovery
seonghobae Sep 9, 2026
925ea90
docs(operability): define lifecycle recovery and p95 evidence
seonghobae Sep 9, 2026
781f931
fix(tool-capability): verify durable head before lifecycle append
seonghobae Sep 9, 2026
562d52c
test(tool-capability): bind activation to exact approval scope
seonghobae Sep 9, 2026
dd331d8
fix(tool-capability): bind activation to exact approval scope
seonghobae Sep 9, 2026
510f419
test(tool-capability): use canonical approval evidence identities
seonghobae Sep 9, 2026
6ac6069
test(tool-capability): reject forged approval and scope references
seonghobae Sep 9, 2026
5c441bf
docs(traceability): bind external-extension lifecycle evidence
seonghobae Sep 9, 2026
6b9d51f
docs(recovery): define external-extension lifecycle recovery authority
seonghobae Sep 9, 2026
fe3fd5e
docs(prd): make lifecycle evidence requirements code-current
seonghobae Sep 9, 2026
fb88498
docs(trd): specify durable extension lifecycle mechanics
seonghobae Sep 9, 2026
6906d71
docs(architecture): map lifecycle evidence recovery boundary
seonghobae Sep 9, 2026
0af817b
docs(uml): model lifecycle append and recovery flows
seonghobae Sep 9, 2026
f1461bb
merge protected main after #566 into external extension lifecycle lane
seonghobae Sep 9, 2026
71f5788
test(tool-capability): cover malformed approval scope evidence
seonghobae Sep 9, 2026
589cbf6
test(tool-capability): pin canonical scope byte ordering
seonghobae Sep 9, 2026
6b62b12
fix(tool-capability): make scope digests runtime-independent
seonghobae Sep 9, 2026
7cae6b6
docs(tool-capability): specify canonical scope digest ordering
seonghobae Sep 9, 2026
85c2d7d
test(tool-capability): reject impossible approval instants
seonghobae Sep 9, 2026
53b04ce
fix(tool-capability): require canonical approval instants
seonghobae Sep 9, 2026
cab250b
test(tool-capability): reject impossible lifecycle occurrence instants
seonghobae Sep 9, 2026
0e7b24d
fix(tool-capability): reject impossible lifecycle occurrence instants
seonghobae Sep 9, 2026
f3c4343
Merge protected main into external-extension lifecycle lane
seonghobae Sep 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 28 additions & 1 deletion ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,25 @@ These are separate ownership domains. Noema does not duplicate their internal au

This revision adds a candidate Tool / Capability admission port at `src/tool-capability/external-extension-admission.ts` for external Claude community plugins. It is not an HTTP route and does not change `/health`, `/ready`, or `/exchange`. Marketplace discovery, Anthropic review, and plugin packaging are not runtime authority. The port stays a local fail-closed ACL until an immutable `context-graph-contracts` artifact contract exists.

Candidate PR #574 adds a durable lifecycle aggregate behind that admission boundary without expanding foreign ownership. `src/tool-capability/external-extension-lifecycle-store.ts` partitions one event stream by the complete exact extension/source/artifact identity and persists Noema lifecycle transition/version/head authority plus immutable Policy / Approval, AppGuardrail, quarantine/isolation, and Egress references/digests. It does not persist mutable scanner verdicts, quarantine runtime truth, outbound policy bodies, provider routing, raw secrets, product payloads, or hidden reasoning.

```mermaid
flowchart LR
A[Exact admitted extension/source/artifact] --> L[Noema lifecycle append]
P[Noema Policy / Approval port] -->|fresh evidence for new active| L
S[AppGuardrail evidence reference/digest] --> L
Q[Quarantine/isolation reference/digest] --> L
E[Egress policy reference] --> L
L --> V{expected version/state/head CAS}
V -->|win| EVT[Append-only lifecycle event]
EVT --> IDX[Transition-id replay index]
EVT --> H[Compact current head]
H --> C[readCurrent: verify exact tail]
EVT --> A2[readAudit: verify complete prefix]
```

The arrows from foreign owners carry immutable evidence identities only. Noema does not become their source of truth.

## 5. Evidence and authority separation

| Plane | Meaning | Not equivalent to |
Expand Down Expand Up @@ -111,6 +130,8 @@ Model-facing automation uses the `NOEMA_LLM_*` gateway contract where applicable

Durable Object alarms are at-least-once. Handlers reread current deadline/expiry state and **reschedule** from current state so delayed alarms cannot delete newer state. Storage-class, binding-name, or lifecycle changes require migration/rollback analysis.

Candidate #574 adds separate Durable Object storage semantics for external-extension lifecycle evidence. The event log is append-only and is not the bounded Workflow / Task receipt ledger. Event/request digests are computed outside the short transaction; the transaction revalidates expected version, prior state, and prior head digest before atomically writing event + idempotency index + compact head. `readCurrent()` verifies only the head and exact tail for the latency-sensitive path, whereas `readAudit()` verifies every retained version/hash link and final head/tail identity. Corrupt or truncated durable state is a conflict, never an empty stream. Recovery and rollback must preserve acknowledged history and follow `docs/external-extension-lifecycle-recovery.md`.

## 9. Standalone and modular MSA contract

- **Standalone first:** Noema can deploy, roll back, expose readiness, and serve its core API without another CWL service.
Expand All @@ -127,6 +148,7 @@ Durable Object alarms are at-least-once. Handlers reread current deadline/expiry
| `/exchange` | typecheck, realistic public/API regressions, exact owned-production coverage, security scan |
| OIDC/GitHub App | issuer/audience/repository/workflow-ref, immutable workflow-source SHA when configured, malformed token/JWKS, replay, redirect/egress, secret non-disclosure regressions |
| Durable Objects | cross-instance semantics, delayed/retried alarm, current-state reschedule, malformed backend/storage-failure tests |
| External-extension lifecycle | legal-edge validation; restart/replay/CAS races; exact Policy / Approval and foreign-owner reference binding; corruption/truncation/cross-stream rejection; >128-transition auditability; O(1) verified current projection; full audit/recovery rehearsal; actual Durable Object p95/contention/storage-growth evidence before runtime acceptance |
| GitHub Actions/control plane | least privilege, exact-head/live-base binding, full pagination, stale-head refusal, evidence-class separation |
| LLM integration | gateway contract, provider-key isolation, deterministic gates independent of model judgement |
| release/acquisition | protected source, CI/security/coverage, package/SBOM/provenance/reproducibility, licensing/NOTICE, rollback/recovery, later operational/buyer evidence |
Expand All @@ -137,12 +159,15 @@ Owned production remains subject to exact 100% statement/branch/function/line co

Repository source/docs cannot fabricate stronger live `main` governance than the current ruleset, independent approval, App provisioning, reviewer staffing, protected production approval, immutable release/signing/provenance, 30-day KPI evidence, customer/revenue evidence, or legal transfer authority. These remain separate evidence classes and fail closed when required but absent.

Candidate lifecycle source also cannot establish actual Durable Object p95, contention/partition behavior, backup/restore success, production recovery, or deployed invocation enforcement by documentation alone. Those remain later exact operational evidence.

## 12. Canonical documentation graph

- `docs/PRD.md`, `docs/TRD.md`
- `docs/adr/README.md`
- `docs/UML.md`, `docs/ERD.md`
- `docs/TEST_STRATEGY.md`, `docs/OPERABILITY.md`
- `docs/external-extension-lifecycle-recovery.md`
- `docs/TRACEABILITY.md`
- `docs/product-technical-gap-baseline.md`
- protected `openapi.json` and `docs/api-spec.md`
Expand All @@ -157,4 +182,6 @@ Root README/customer copy may have a separate active owner; the canonical archit

The default shape is **small credential-exchange service + explicit state coordinators + external orchestration/review planes**. New model orchestration, artifact processing, repository mutation, or deployment authority should first be evaluated as a separate bounded component rather than folded into `/exchange`.

Architecture changes must keep source behavior, realistic regression tests, canonical documentation, traceability, and CHANGELOG semantics consistent without promoting active-PR behavior to protected truth.
The external-extension lifecycle remains a bounded Tool Capability / State / Checkpoint aggregate rather than a new scanner, quarantine runtime, egress engine, identity provider, or model router. Its synchronous projection path and full audit/recovery path are deliberately separate so buyer/runtime latency does not require scanning retained history while recovery still verifies the complete chain.

Architecture changes must keep source behavior, realistic regression tests, canonical documentation, traceability, and CHANGELOG semantics consistent without promoting active-PR behavior to protected truth.
8 changes: 6 additions & 2 deletions docs/CONTEXT_MAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,18 @@ Protected `main` also includes the durable execution slice integrated through #5

Owns versioned allowlisted tool/capability descriptors, least-authority invocation, expiry, input/output bounds, and capability provenance. Arbitrary caller/model shell or network authority is not a Noema tool contract.

This revision adds a local fail-closed admission port for external Claude community plugins (`src/tool-capability/external-extension-admission.ts`, ADR 0015, issue #545). Marketplace metadata, Anthropic review, mutable branch/tag refs, and plugin instructions are not admission authority. Exact repository/commit/path/digest identity, independently pinned AppGuardrail and quarantine receipts, product/role scope, expiry/rollback, and idempotent activation/invocation receipts are. Product-runtime execution of a Claude plugin wrapper is rejected. Until `context-graph-contracts` publishes an immutable shared artifact contract, this port is a local ACL/test double rather than a released shared-kernel dependency. The slice is candidate truth on this revision until protected integration.
Protected `main` includes a local fail-closed admission port for external Claude community plugins (`src/tool-capability/external-extension-admission.ts`, ADR 0015, issue #545). Marketplace metadata, Anthropic review, mutable branch/tag refs, and plugin instructions are not admission authority. Exact repository/commit/path/digest identity, independently pinned AppGuardrail and quarantine receipts, product/role scope, expiry/rollback, and idempotent activation/invocation receipts are. Product-runtime execution of a Claude plugin wrapper is rejected. Until `context-graph-contracts` publishes an immutable shared artifact contract, this port is a local ACL/test double rather than a released shared-kernel dependency.

Draft #574 extends that boundary with candidate append-only lifecycle evidence for issue #561. One lifecycle stream is partitioned by `external_extension_id` plus exact admitted repository/commit/path/artifact identity. Noema persists its own transition/version/head authority and immutable owner-issued references/digests only; AppGuardrail verdict bytes, quarantine execution truth, isolation policy, Egress authority, identity secrets, and contextual-orchestrator routing remain with their canonical owners. A genuinely new `active` transition must re-read fresh Policy / Approval and owner evidence before the CAS append. An exact transition already committed remains immutable historical evidence and replays without treating later owner-state drift as retroactive revocation. This paragraph describes Draft candidate behavior, not protected or released capability.

### State / Checkpoint

Owns versioned runtime checkpoint semantics needed for restart/cancellation/idempotency. Checkpoints contain only Noema runtime state and canonical foreign references; they must not copy another product's domain truth, provider credential state, or unrestricted reasoning/tool payloads.

Protected `main` includes checkpoint admission for one retained execution identity. Sequence zero initializes the checkpoint stream; an exact same-sequence/same-digest replay is idempotent; conflicting replay, stale or gapped sequence, cross-execution identity, non-canonical execution identity, and non-SHA-256 state evidence fail closed. Returned checkpoint metadata is detached and frozen so caller-owned aliases cannot mutate admitted authority after validation. The #542 durable state store binds persisted transitions to retained execution-plan and claim authority and rejects malformed, contradictory, stale, gapped, cross-execution, or provenance-invalid stored records. This does not grant foreign-domain truth or external side-effect success authority.

Draft #574 reuses the same Durable Object storage/transaction family for external-extension lifecycle State / Checkpoint evidence rather than introducing another database authority. Transition digests are computed outside the short write transaction; the serialized write rechecks expected version, prior state, and prior head digest before appending the event and updating the current projection. The current-state path verifies the compact head and its exact audit tail with O(1) storage cardinality, while audit/recovery verifies the complete retained digest chain. The lifecycle log is deliberately not the workflow store's bounded 128-receipt observability ring. Real Durable Object p95, contention, storage-growth, rebuild, and recovery evidence remain acceptance work and are not inferred from unit tests.

## Upstream and downstream boundaries

### contextual-orchestrator
Expand Down Expand Up @@ -108,4 +112,4 @@ No dependency arrow grants source-write authority to the upstream or downstream

## Acceptance for a new runtime slice

A new runtime slice is acceptable only when it has a named owning context, realistic cancellation/restart/checkpoint/idempotency/tool-policy/concurrency/isolation tests as applicable, bounded side effects, exact observability, and an explicit foreign-authority contract. A feature that requires direct provider routing, arbitrary tool authority, ambient secret propagation, unbounded recursion, silent retry, cross-service SQL, or unreleased Context Graph source is outside the accepted Noema boundary.
A new runtime slice is acceptable only when it has a named owning context, realistic cancellation/restart/checkpoint/idempotency/tool-policy/concurrency/isolation tests as applicable, bounded side effects, exact observability, and an explicit foreign-authority contract. A feature that requires direct provider routing, arbitrary tool authority, ambient secret propagation, unbounded recursion, silent retry, cross-service SQL, or unreleased Context Graph source is outside the accepted Noema boundary.
Loading
Loading