Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
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
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- Add a Noema-owned exact-claim evidence receipt contract whose execution and research producers serialize one canonical artifact that binds every receipt semantic field, including command/result/isolation/network or source revision/excerpt/retrieval policy. Admission accepts only a receipt ID from untrusted model output. The owner API first verifies the exact authenticated OpenCode-handoff manifest digest, canonical envelope bytes, reviewed producer-to-kind policy, and repository/head/workflow/run/attempt identity before it can construct an immutable typed index; admission then reconstructs each canonical artifact and verifies time/claim/artifact identity. The version-2 manifest now binds a separate producer-authenticated `ClaimEvidenceRequirement` containing the exact claim, independently required evidence kind, and `context` or `finding` publication authority. Raw current-head source lines are context only: they are withheld from finding-reference prompts and cannot publish a finding or `request_changes`; an explicitly producer-authorized source finding remains usable and retains exact path/line checks. Finding-free model `request_changes` and `blocked` verdicts cannot bypass receipt admission to publish a vacuous blocking review. Requirement/receipt kind mismatch, fixed-artifact semantic substitution, caller-supplied receipt dictionaries, model self-classification, stale identities, cross-kind receipts, marker-only sandbox output, noncanonical artifact bytes, and expired receipts fail closed before the GitHub publisher. This remains the owner prerequisite for ContextualWisdomLab/.github#1641 and issue #555. The reviewed `sandboxed_verify` adapter exists in owner source, but its actual central stdout/stderr/marker-to-manifest wiring and the trusted research producer are not yet integrated; exact-head hosted GREEN, immutable release, and the verified central consumer bump remain required.

## Unreleased
- Protected #704 exact `42b15e865bdf88fde622c3bba2c0b123770d18be`, integrated by GitHub-verified normal merge `e8c2002e5af8fa5611880091dab81916bb716c35`, requires Agent Runtime to admit private Workflow / Task Execution current-state evidence only when a successful response declares the owner-emitted JSON media type application/json with optional `charset=utf-8` parameter; other media-type parameters are rejected. Missing or non-JSON media types fail closed with the stable `invalid_workflow_state_response` classification before bounded parsing. Rejected-media body cancellation is best-effort cleanup: synchronous throw, asynchronous rejection, null body, or non-settling cleanup cannot replace or delay the fail-closed decision. The existing fixed 1 MiB retained buffer, 10-second absolute read deadline, fatal UTF-8/JSON admission, canonical execution binding, and reader-lock lifecycle remain unchanged. Workflow / Task lifecycle truth, provider/model routing, destination/outbound policy, credential authority, quarantine/security, Policy / Approval, State / Checkpoint, release/deployment, and foreign-domain authority remain with their existing owners; protected source/checks/merge are not an immutable release, deployed Durable Object recovery, or production p95/heap evidence.
- Protected #702 exact `2b31805eb2b81b6078fefe1ebcce8007b6ca5169`, integrated by GitHub-verified normal merge `cf7f4279dbf83213557e987f0ee8fb52b12fcccf`, behaviorally verifies Noema's shared Cloudflare deploy/status/recovery request boundary rather than relying on source-text header presence. The three direct clients use `requestCloudflareJson`; executable tests observe the actual `fetch` request, require `Accept: application/json` and the owner bearer to override conflicting caller values, preserve unrelated caller headers such as `Content-Type`, enforce the existing 120-second request deadline, and continue into the 1 MiB bounded JSON reader. `Accept` remains request-side representation preference rather than provider response-shape authority. Cloudflare/provider truth, destination/outbound policy, credential authority, quarantine/security, recovery-state, release/deployment and foreign-domain authority remain with their existing owners; protected source/test/CI evidence is not an immutable release, production deployment, controlled recovery rehearsal, deployed p95/heap or production KPI evidence.
- PR #701 source exact `80d3d579ad4a08ccb3f21e2735c7fb0bebc7b492` makes Noema's direct Cloudflare deploy/status/recovery control-plane clients explicitly negotiate machine-readable Cloudflare-generated errors with `Accept: application/json` before their existing 1 MiB bounded JSON response reader. Cloudflare's 2026-05-05 error-response contract documents HTML as the default for generated errors when `Accept` is absent or `*/*`, and structured JSON when `application/json` is requested; Noema still treats negotiation as preference rather than shape authority and retains fail-closed fatal UTF-8/JSON/provider-error admission. Existing 120-second request bound, fixed retained buffer, reader/cancellation lifecycle, exact recovery-state checks, credential capability, destination/outbound policy, Cloudflare/provider authority and release/deployment authority remain unchanged. This source PR is not an immutable release, production deployment, controlled recovery rehearsal, or deployed p95/heap evidence.
- Protected #699 bounds Agent Runtime's private Workflow / Task Execution current-state response read at exact source `e52408745efc73351c098227ae4c85c309fdd0c9` with a 10-second absolute read deadline. Deadline expiry preserves the stable `invalid_workflow_state_response` fail-closed contract, requests reader cancellation only as best-effort cleanup, clears the deadline timer, and releases the reader lock on every terminal path. The existing fixed 1 MiB retained buffer, byte ceiling, fatal UTF-8/JSON admission, canonical execution binding, and Workflow / Task Execution ownership remain unchanged. Workflow / Task lifecycle, provider/model routing, outbound, credential, quarantine/security, release/deployment, and foreign-domain authority stay with their existing owners; this protected source is not an immutable release, deployed Durable Object recovery, or production p95/heap evidence. PR #699.
Expand Down Expand Up @@ -53,7 +54,7 @@
- `noema-core` provider-neutral Shared Kernel을 추가하여 이미 해석된 PydanticAI `Model`과 역할별 prompt/schema만 받아 Agent를 구성한다. 문자열 model identifier와 provider discovery·credential·routing·retry·failover는 Shared Kernel 밖에 두고 `Agent(..., retries=0)`으로 repository-local model-attempt authority를 만들지 않는다. Reviewer wheel·sdist·editable 설치는 canonical `packages/noema-core` source를 포함하거나 참조하며 별도 100% coverage·docstring과 clean install smoke로 검증한다. 외부 소비는 immutable versioned publication·exact source identity·SBOM/provenance·licensing/NOTICE·compatibility/rollback evidence 전에는 허용하지 않는다.
- `writeAcquisitionPrivateFile`의 기존 대상 사전-교체 검증 read(`existingDescriptor` open)에 `O_NONBLOCK`을 추가해 fail-closed를 강화한다. 이 open은 이미 필수 filesystem capability로 `O_NONBLOCK`을 검증했지만 실제로는 사용하지 않아, 로컬 권한을 가진 행위자가 사전 `lstatSync` 정규 파일 확인과 이 open 사이에 대상 경로를 FIFO로 교체하면 writer가 나타날 때까지 무한정 블로킹해 writer lease를 계속 점유할 수 있었다. `O_NONBLOCK`은 정규 파일에는 영향이 없고, FIFO에서는 open이 즉시 반환되어 이어지는 descriptor 타입 검증이 그대로 fail-closed로 거부한다. 회귀 테스트(`test/acquisition-private-output-existing-target-nonblocking.test.ts`)와 기존 open-flags 계약 테스트 갱신으로 고정했다.
- `readStableFile`의 close-후 재검증 단계(`afterClosePath` lookup 실패)와 `writeAcquisitionPrivateFile`의 cleanup-시점 `O_NONBLOCK` 소실 분기에 대한 fail-closed 회귀 테스트를 추가해 `scripts/lib/acquisition-data-room-integrity.mjs`/`scripts/lib/acquisition-private-output.mjs`의 100% coverage 게이트를 복구한다. 동작 변화는 없다.
- Noema reviewer의 strict changed-file evidence를 historical 12-file prefix에서 canonical 80-file CodeGraph scope와 일치시켰다. 13–80 file PR은 선택된 모든 current-head file context를 유지하고 81개 이상은 기존처럼 실패-폐쇄하며, local CodeGraph fallback의 `HOME`·`TEMP`·`TMP`·`TMPDIR`은 ambient host path를 상속하지 않고 실행마다 새 private temporary directory로 격리한다.
- Noema reviewer의 strict changed-file evidence를 historical 12-file prefix에서 canonical 80-file CodeGraph scope와 일치시켰다. 13–80 file PR은 선택된 모든 current-head file context를 유지하고 81개 이상은 기존처럼 실패-폐쇄하며, local CodeGraph fallback의 `HOME`·`TEMP`·`TMPDIR`은 ambient host path를 상속하지 않고 실행마다 새 private temporary directory로 격리한다.
- Workflow / Task Execution은 untrusted DAG를 execution/plan identity에 결합한 detached immutable snapshot으로 승인하고, validated array bounds 안에서만 task/dependency/state evidence를 읽는다. runnable 선택은 cross-execution·foreign·duplicate·non-canonical evidence, admitted concurrency를 초과한 running state, 성공하지 않은 prerequisite 뒤에 존재하는 causally impossible executed state를 실패-폐쇄하며, 선택 결과는 reservation이나 side-effect authority가 아닌 후보임을 명시한다. Agent Runtime lifecycle·State & Checkpoint·Workflow admission은 null·throwing accessor·revoked proxy 같은 malformed runtime input의 임의 JavaScript 예외를 각 bounded-context domain error로 정규화한다.
- State & Checkpoint admission은 accepted/replay 결과와 내부 checkpoint를 모두 caller-owned alias에서 분리한 frozen snapshot으로 반환한다. TypeScript `readonly`만으로는 막을 수 없는 JavaScript 런타임 alias mutation이 승인된 checkpoint authority나 `accepted`/`replay` 분류를 사후 변경하지 못하도록 실패-폐쇄한다.
- Noema의 필수 PR 워크플로 `ci`, `reviewer-ci`, `patch-validator-image`를 부동 `ubuntu-latest` 대신 명시적 `ubuntu-24.04` GitHub-hosted runner에 고정하고, 인용 여부와 무관하게 `ubuntu-latest` 회귀를 탐지하는 계약 테스트를 추가해 pre-checkout runner-assignment stall의 repository-owned selector 원인을 제거한다. 중앙 `Security Scan`의 runner/control-plane 권한은 별도 `.github` owner 경계에 유지한다.
Expand Down
8 changes: 8 additions & 0 deletions docs/product-technical-gap-baseline.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,3 +154,11 @@ The existing 65,536-byte ceiling, optional caller-supplied deadline with no inve
Protected history includes merged PR #699 exact `e52408745efc73351c098227ae4c85c309fdd0c9`. Protected #699 closes the stalled-read liveness gap on Agent Runtime's private Workflow / Task Execution current-state response path: after successful reader acquisition, a 10-second absolute read deadline prevents an HTTP 200 response that never yields another chunk from pinning procedural guidance indefinitely. Deadline expiry preserves the stable `invalid_workflow_state_response` fail-closed contract, requests cancellation only as best-effort cleanup, clears the deadline timer, and releases the reader lock on every terminal path.

The existing fixed 1 MiB retained buffer, byte ceiling, fatal UTF-8/JSON admission, canonical execution binding, and Workflow / Task Execution ownership remain unchanged. #699 remains protected source/test evidence; immutable release, deployed Durable Object recovery, and production p95/heap evidence remain separate. Workflow / Task lifecycle, provider/model routing, outbound, credential, quarantine/security, release/deployment, and foreign-domain authority stay with their existing owners.

## Protected procedural current-lifecycle media admission — merged PR #704

Protected history includes merged PR #704 exact `42b15e865bdf88fde622c3bba2c0b123770d18be`, integrated by GitHub-verified normal merge `e8c2002e5af8fa5611880091dab81916bb716c35`. Protected #704 closes the representation-admission gap on Agent Runtime's private Workflow / Task Execution current-state response path: successful owner evidence must identify its representation as application/json with optional `charset=utf-8` parameter; other media-type parameters are rejected before Noema performs bounded procedural-state parsing. Missing or non-JSON media types fail closed with the stable `invalid_workflow_state_response` classification.

Rejected-media response-body cancellation is best-effort cleanup only: synchronous cleanup throw, asynchronous rejection, null body, or non-settling cancellation cannot replace or delay the fail-closed decision. The existing fixed 1 MiB retained buffer, byte ceiling, 10-second absolute read deadline, fatal UTF-8/JSON admission, canonical execution binding, and reader-lock lifecycle after successful acquisition remain unchanged.

#704 remains protected source/test evidence; immutable release, deployed Durable Object recovery, and production p95/heap evidence remain separate. Workflow / Task lifecycle truth stays with its Durable Object owner. #704 does not transfer provider/model routing, destination/outbound policy, credential authority, quarantine/security, Policy / Approval, State / Checkpoint, release/deployment, or foreign-domain authority into Agent Runtime.
31 changes: 31 additions & 0 deletions test/procedural-current-lifecycle-media-authority.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { readFileSync } from "node:fs";

import { describe, expect, it } from "vitest";

describe("protected procedural current-lifecycle media documentation authority", () => {
it("records protected #704 without promoting Workflow / Task or production authority", () => {
const baseline = readFileSync("docs/product-technical-gap-baseline.md", "utf8");
const changelog = readFileSync("CHANGELOG.md", "utf8");
const source = readFileSync("src/agent-runtime/procedural-current-lifecycle.ts", "utf8");

expect(changelog).toContain("Protected #704");
expect(changelog).toContain("42b15e865bdf88fde622c3bba2c0b123770d18be");
expect(changelog).toContain("e8c2002e5af8fa5611880091dab81916bb716c35");
expect(changelog).toContain("application/json with optional `charset=utf-8` parameter");
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
expect(changelog).toContain("invalid_workflow_state_response");
expect(changelog).toContain("best-effort cleanup");

expect(baseline).toContain(
"merged PR #704 exact `42b15e865bdf88fde622c3bba2c0b123770d18be`",
);
expect(baseline).toContain("GitHub-verified normal merge `e8c2002e5af8fa5611880091dab81916bb716c35`");
expect(baseline).toContain("application/json with optional `charset=utf-8` parameter");
expect(baseline).toContain("stable `invalid_workflow_state_response`");
expect(baseline).toContain("best-effort cleanup");
expect(baseline).toContain("immutable release");
expect(baseline).not.toContain("#704 transfers Workflow / Task lifecycle authority to Agent Runtime");

expect(source).toContain("function isJsonMediaType(value: string | null): boolean");
expect(source).toContain("Noema current workflow-state response used an unsupported media type");
});
});
Loading