Skip to content

github-devloop implementation for #2848#2852

Open
jason-aelf wants to merge 2 commits into
auto-work-dev-0701from
devloop/issue/aevatarAI/aevatar/2848/ready-github-devloop-issue-aevatarAI-aevatar-2848-intake-4013740452-0308614472
Open

github-devloop implementation for #2848#2852
jason-aelf wants to merge 2 commits into
auto-work-dev-0701from
devloop/issue/aevatarAI/aevatar/2848/ready-github-devloop-issue-aevatarAI-aevatar-2848-intake-4013740452-0308614472

Conversation

@jason-aelf

Copy link
Copy Markdown
Collaborator

github-devloop implementation PR for issue #2848

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop PR child open

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop PR is ready for review

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop PR is ready for review

@jason-aelf jason-aelf added the fkst-dev:reviewing pr-review-consensus-in-progress label Jul 20, 2026
@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop PR review decision: reject
Verdicts: teleology=reject parsimony=reject fidelity=reject natural-ownership=reject proportional-containment=reject
Blocking gap: missing request-size limit

teleology:
Established workflow/security practice for arbitrary outbound HTTP is a typed HTTP node whose authentication carriers are opaque vault refs, not user-authored durable header values. I defend reject: the peers’ missing request-size limit and missing scope egress policy claims identify further unmet controls, but they do not defeat the root blocker for a PR titled "secret-backed authentication". The implementation models raw headers directly on WorkflowHttpRequestOptions (src/workflow/Aevatar.Workflow.Abstractions/workflow_execution_messages.proto:504), rejects only the literal "Authorization" header via ContainsRawAuthorizationHeader (src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs:730), then forwards every remaining configured header with TryAddWithoutValidation (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:141). No proof is given that common credential headers such as "X-Api-Key" are non-authentication data, so raw credentials can still enter workflow YAML and be sent without authentication.secret_ref; that fails the stated requirement that raw credentials never enter workflow text/read paths.

parsimony:
I defend: teleology's raw credential header bypass and fidelity's missing scope egress policy add possible blockers, but neither defeats the already goal-blocking root. Established outbound HTTP/SSRF practice treats request and response byte caps as one executor-owned boundary; this issue explicitly required request-size protection. The typed WorkflowHttpRequestOptions has body and max_response_bytes, but no max_request_bytes (src/workflow/Aevatar.Workflow.Abstractions/workflow_execution_messages.proto:506, src/workflow/Aevatar.Workflow.Abstractions/workflow_execution_messages.proto:509), and the executor sends the body as StringContent (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:164). No peer evidence shows an existing request-size limit elsewhere, so the PR is still not merge-ready.

fidelity:
Established SSRF/least-privilege practice for user-authored workflow HTTP is source-owned deny-by-default egress authorization, with transport hardening as a lower layer. I defend Phase B: the peer missing request-size limit and raw credential header bypass claims are real, but even if fixed they would not satisfy the root requirement Apply Team/Scope authorization and outbound egress policy. The evaluator only makes WorkflowServiceGrantPolicy depend on NyxID proxy slugs (src/workflow/Aevatar.Workflow.Core/WorkflowAuthorizationDependencyEvaluator.cs:51), the new http_request test asserts WorkflowServiceGrantPolicy.NotRequiredNoExternalService for https://api.example.com/items (test/Aevatar.Workflow.Core.Tests/WorkflowHttpRequestPrimitiveTests.cs:92), and runtime only sets executor-local network policy such as AllowPrivateNetwork = false (src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs:778). SSRF filtering is necessary, but it is not proof that this Team/Scope may call this URL.

natural-ownership:
Defend: the decisive root reason remains natural ownership of outbound HTTP safety. Established workflow/SSRF practice puts resource-exhaustion limits at the shared egress executor, and the pinned issue required "Enforce request and response size limits". The diff still models WorkflowHttpRequestOptions with request body and response-only limit fields, with no request-byte counterpart in that contract (src/workflow/Aevatar.Workflow.Abstractions/workflow_execution_messages.proto:499); the executor clamps only MaxResponseBytes (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:55); then it sends any non-empty body as StringContent without a request-size check (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:164). Teleology's and fidelity's alternative blockers do not move the seat because they do not prove this established bound is enforced elsewhere or inapplicable.

proportional-containment:
Established SSRF/workflow outbound-HTTP practice treats arbitrary user-authored egress as one hardened executor boundary with both request and response byte caps. I defend my Phase B root blocker: parsimony and natural-ownership independently corroborate missing request-size limit, while teleology's raw credential header bypass and fidelity's missing scope egress policy do not defeat the simpler stated security failure. The workflow path still forwards Body = ResolveBody(request.Payload) and only MaxResponseBytes into the executor (src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs:772, src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs:775), and the executor sends any non-empty body through StringContent without a byte check (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:164). That leaves the required request-size protection unimplemented at the shared transport owner, so the PR is not merge-ready.

⟦AI:FKST⟧

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate failed: missing request-size limit
Reproduce locally with scripts/run.sh test from the repository root.

@jason-aelf jason-aelf added fkst-dev:fixing review-rejected-and-fix-in-progress and removed fkst-dev:reviewing pr-review-consensus-in-progress labels Jul 20, 2026
@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop fix pushed for re-review

Previous reviewed head: 54ac550
New head: fff70ff

@jason-aelf jason-aelf added fkst-dev:reviewing pr-review-consensus-in-progress and removed fkst-dev:fixing review-rejected-and-fix-in-progress labels Jul 20, 2026
@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop PR is ready for review

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop PR review decision: approve
Verdicts: teleology=approve parsimony=approve fidelity=approve natural-ownership=approve proportional-containment=approve

teleology:
ESSENCE: arbitrary user-authored workflow HTTP must make the concrete request and its safety bounds first-class, not proxy through a named connector. IDEAL: one typed http_request contract over a shared hardened executor with opaque secret resolution and egress/resource caps. Under established workflow/SSRF practice, the prior blocker is closed: max_request_bytes is now a typed WorkflowHttpRequestOptions field (src/workflow/Aevatar.Workflow.Abstractions/workflow_execution_messages.proto:512), the workflow path forwards MaxRequestBytes into the outbound request (src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs:775), and the shared executor rejects bodies over the limit before dispatch (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:67). Six-smell comparison: within the re-review scope, no evidenced magic-number, proxy-over-truth, symptom-branch, narrative-over-verification, missing-inevitability, or skipped-purpose blocker remains; the fix makes the request-size bound part of the purposeful form rather than an after-the-fact branch.

parsimony:
Established practice for arbitrary workflow HTTP is one hardened egress executor with explicit byte caps, not per-call patches. Essence: the prior blocker was that http_request could send an unbounded body while only response bytes were capped; ideal: carry one typed request limit from workflow options into the shared executor and reject before dispatch. The named gap is closed: the direct adapter forwards MaxRequestBytes into OutboundHttpRequest (src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs:775), the shared executor rejects oversized UTF-8 bodies before sending (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:67), and the regression test is explicitly ExecuteAsync_ShouldRejectRequestBodyThatExceedsLimitBeforeSending (test/Aevatar.Foundation.Core.Tests/OutboundHttpRequestExecutorTests.cs:120). Six-smell comparison: no remaining parsimony blocker; magic numbers are contained as named policy defaults, proxy-over-truth is reduced by typed request options, symptom branches are avoided by using the shared executor, and I see no narrative-over-verification, missing-inevitability, or skipped-purpose gap inside this re-review scope.

fidelity:
Established practice for arbitrary workflow HTTP is a typed node over a shared hardened executor with explicit body/response limits; the prior blocker was missing request-size limit. That gap is closed: WorkflowHttpRequestOptions now has max_request_bytes (src/workflow/Aevatar.Workflow.Abstractions/workflow_execution_messages.proto:512), the workflow module forwards MaxRequestBytes into OutboundHttpRequest (src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs:775), and the executor rejects an oversized UTF-8 body before building/sending the request (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:67). No evidenced BEAUTY-GATE blocker remains in this re-review scope; treating total URL/header byte accounting as future tightening would be advisory, not the named gap.

natural-ownership:
Established workflow/SSRF resource-exhaustion practice puts request-byte enforcement at the shared outbound HTTP executor, the layer with semantic responsibility and causal control over dispatch. ESSENCE: user-authored http_request bodies must not be unbounded. IDEAL: a typed workflow option flows into OutboundHttpRequest, then one hardened executor rejects oversize bodies before network send. The named gap is closed: max_request_bytes is now a typed WorkflowHttpRequestOptions field (src/workflow/Aevatar.Workflow.Abstractions/workflow_execution_messages.proto:512), the workflow module passes options.MaxRequestBytes into the outbound request (src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs:775), and DefaultOutboundHttpRequestExecutor clamps and rejects an oversized body before dispatch (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:56). Six-smell comparison against that ideal: no remaining magic-number blocker because the default is named, no proxy-over-truth because the typed field reaches the executor, no symptom branch because enforcement lives at the shared transport owner, no narrative-over-verification blocker in source scope, and no missing-inevitability or skipped-purpose regression within this re-review boundary.

proportional-containment:
ESSENCE: the named rejection was not about making HTTP a universal integration law, but about the established workflow/SSRF containment rule that arbitrary user-authored outbound HTTP needs a request-size cap at the hardened egress boundary. IDEAL: the natural owner is the shared IOutboundHttpRequestExecutor, fed by typed http_request options and reused by named HTTP connectors. The new head closes that gap: WorkflowHttpRequestOptions now carries max_request_bytes (src/workflow/Aevatar.Workflow.Abstractions/workflow_execution_messages.proto:512), ConnectorCallModule forwards it as MaxRequestBytes (src/workflow/Aevatar.Workflow.Core/Modules/ConnectorCallModule.cs:775), and DefaultOutboundHttpRequestExecutor rejects oversized bodies before dispatch (src/Aevatar.Foundation.Core/Connectors/DefaultOutboundHttpRequestExecutor.cs:67). Six-smell comparison: no blocking magic-number, proxy-over-truth, symptom-branch, narrative-over-verification, missing-inevitability, or skipped-purpose smell remains in the re-review scope; the fix is proportionally contained at the transport owner rather than hoisted into Studio or generalized beyond HTTP egress.

⟦AI:FKST⟧

@jason-aelf jason-aelf added fkst-dev:merge-ready review-approved-and-ready-to-merge and removed fkst-dev:reviewing pr-review-consensus-in-progress labels Jul 20, 2026
@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop merge gate wait: ci-unknown

@jason-aelf

jason-aelf commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator Author

github-devloop timeout redrive attempt: merge-ready 2

⟦AI:FKST⟧

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop timeout reconcile action: drop

Reason:
state-output-obligation-timeout-after-3-attempts

Structured WHY:
reason_class=external-ci-wait-expired
from_state=merge-ready
from_version=ready/github-devloop/issue/aevatarAI/aevatar/2848/intake/4013740452/review-loop/1/fix/1/fix/2
age_minutes=406
budget_minutes=390
attempt=3
attempt_limit=3
driving_queue=devloop_merge_ready
source_ref.kind=external
source_ref.ref=aevatarAI/aevatar#pr/2852

⟦AI:FKST⟧

@jason-aelf jason-aelf added fkst-dev:blocked devloop-blocked-terminal and removed fkst-dev:merge-ready review-approved-and-ready-to-merge labels Jul 20, 2026
@jason-aelf

jason-aelf commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator Author

github-devloop timeout redrive attempt: blocked 2

⟦AI:FKST⟧

@jason-aelf

Copy link
Copy Markdown
Collaborator Author

github-devloop decompose output obligation exhausted

Structured WHY:
reason_class=decompose-output-obligation-timeout
from_state=blocked
from_version=ready/github-devloop/issue/aevatarAI/aevatar/2848/intake/4013740452/review-loop/1/fix/1/fix/2/timeout-reconcile/merge-ready/3
attempt=3

⟦AI:FKST⟧

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

Labels

fkst-dev:blocked devloop-blocked-terminal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant