Repository navigation
Conversation
rmcdaniel
left a comment
There was a problem hiding this comment.
Mechanical PHP call-site review of contract head 9f20c526f1d9ec6e4c8e592cd352a9655bd056b8, pinned SDK 61477048340e8ab374822381a9018df7db050872. Runtime source bytes were checked at that exact pin. No runtime/protection implementation or effect ran.
The inventory is a future v1 implementation scope. Current PHP accepts only plain fixed-schema Value; none of these rows presently implements protection or an enabled-protection refusal. AvroPayloadCodec::encode returns base64 text of c301 + Value fingerprint + datum; envelope puts that string in {codec:"avro",blob:...}.
| Boundary | Pinned PHP source and actual wire field | Current representation / limit |
|---|---|---|
| Workflow input | Client::startWorkflow: input; Model/ScheduleAction.php:23: action.input; Worker/WorkflowCommand.php:910: child/continue commands[].arguments; Worker.php:1920,4534: task entry decoding |
Value envelope; nominated slots may become runtime references. |
| Workflow result | Replayer completion: commands[].result; Client.php:3388: terminal history payload.output/payload.result; Replayer.php:3502: child result decode |
Value envelope, or hydrated nominated reference. |
| Ordinary activity input | WorkflowCommand::toWire: commands[].arguments; Worker.php:3335,4534: task arguments decode |
Value envelope or nominated reference. Local/prepared are separate scope. |
| Ordinary activity result | Client::completeActivityTask and continuation at2684: result; Replayer.php:1870,3502: ActivityCompleted payload result |
Value envelope or nominated reference; continuation command offload has narrower rules. |
| Signal input | Client::signalWorkflow: input; Worker/WorkflowContext.php:887: history value/input/arguments |
Value envelope/reference. This PHP revision has no WorkflowContext outbound signal-external method: the generic workflow-signal write site is not a PHP implementation claim. |
| Update input | Client::updateWorkflowReceipt: input; Worker.php:3902: accepted-history/task arguments |
Value envelope or nominated reference. |
| Update result | Worker update completion: commands[].result; Client.php:1170,3376: retained/wait result_envelope or enveloped result |
Value envelope/reference; current unprotected reader retains raw-result fallback. |
| Query input | Client::queryWorkflow: input; Worker.php:3674: task.query_arguments or task.arguments |
Value envelope/reference. Worker::queryContext is not a method at this pin; correct the inventory anchor to query execution/decodeArguments. |
| Query result | Client::completeQueryTask: result_envelope plus JSON-encodable plaintext result; Client.php:3376: envelope-first reader plus raw fallback |
Protecting only result_envelope leaks the display projection. Enabled mode must omit/refuse the plaintext copy and raw fallback. Current offload sets result=null only when replacing result_envelope. |
| Side-effect result | WorkflowCommand side-effect branch: commands[].result = codec.encode(...); Replayer.php:3502 accepts bare string |
Bare base64 Value single-object bytes, not a JSON envelope; nominated slot can become a reference. |
| External object | RuntimePayloadUploads: upload body is $payload['blob']; exact slots at426, blob extraction at586; RuntimePayloads.php:150 verifies length/hash then hydrates {codec,blob} |
Object body/hash cover the base64 blob text, not raw decoded Avro bytes. Specify that representation before binding vector object hashes. Negotiated storage and typed refusal remain required. |
| Heartbeat details — refuse | Client::heartbeatActivityTask: raw JSON details; Worker.php:4133 checks local heartbeat encodability but records raw details |
No portable protected envelope; enabled-protection refusal is appropriate. |
| Streams — refuse | Client::appendMessageStream: enveloped input; Client.php:941 + Model/WorkflowStreamAppendItem.php:22: items[].payload/payload_reference; workflow-attached stream directives also exist |
Existing Avro/reference representations do not admit v1 stream semantics. Refusal is a scope decision; not all these fields are raw JSON. |
| Nexus — refuse | Client::serviceOperationBody: bare encoded arguments plus payload_codec; WorkflowCommand.php:906: enveloped request_payload |
Existing Value slots do not establish caller/target AAD authority. |
| Local/prepared — refuse | WorkflowCommand::resolveLocalActivity: argument/result envelopes; PreparedLocalActivityRunner.php:154: report.result; uploads at452: descriptor.arguments/report.result |
Some paths already use portable Value envelopes. That does not qualify all persistence/retry paths for protection; refusal is intentional scope. |
| Failure details — refuse | Client::failActivityTask: optional Value failure.details, plaintext message/type/stack/diagnostics; upload slots at445 include exception.details |
Ad hoc details are not an admitted v1 boundary. Do not globally encrypt every existing Avro slot. |
| Unmapped external tasks / raw JSON — refuse | Outbound payload validation, AvroPayloadCodec.php:57 validates fixed framing/schema for declared payloads; raw projections/heartbeat are separate surfaces |
No extra PHP external-task boundary is proven here. Unknown ProtectedValue fingerprint currently fails unsupported_payload_schema, not the future contract error payload_envelope_unsupported. |
The concrete inventory corrections are the missing queryContext anchor, query result's plaintext projection/raw fallback, and base64-text external-object representation. A global codec-only switch cannot implement this scope: WorkflowCommand.php:927 also encodes upsert_memo.entries as Avro while memo remains plaintext metadata, and several intentionally refused paths already use Avro. Conformance must exercise boundary-aware protection/refusal and exact transport representations. This is PHP source feedback only, not approval of other bindings or cryptographic implementation.
|
Mechanical Python source audit for All paths below are relative to that immutable SDK commit. Inline means the existing Avro Value single-object encoded as the
Unsupported-v1 boundaries still have current transports and do not presently refuse merely because a protection mode was selected; Python has no such mode yet:
Two concrete corrections/obligations should be explicit in the inventory/contract before implementation is treated as complete:
The existing helper |
|
Pinned Rust mechanical call-site review at Two current anchors need correction:
For unsupported rows, add the actual Rust anchors rather than treating an Avro carrier as protection admission:
I read these pinned source paths and the exact call-site inventory; no compiler, SDK, Server, network payload or cryptographic implementation ran. The query plaintext shadow/fallback and the broader external-upload whitelist should be explicit implementation obligations in the inventory before any future protection claim. |
|
Pinned Workflow persistence audit for The inventory is a proposed protection contract, not evidence of encryption in this revision. Embedded durable values currently use the codec blob plus a separate codec field. The default Avro blob is base64 single-object For externalized values, a DB text field contains
Required inventory corrections: replace the lifecycle activity-result anchor with the actual outcome writer; add update-result and embedded query anchors; record the inline-only update-input and local-signal/offload distinction; preserve the DB-reference versus history-reference forms. These are mechanical source observations only. No encryption implementation, installed producer or release is qualified by this review. |
|
Native corrections at pinned Server Replace continuing native producer anchors under
Representation corrections:
|
|
Source mapping correction is pushed at This binds every protected boundary to exact pinned SDK, embedded Workflow, and native Server anchors plus its wire/stored fields and inline/external representation. It also records the strict-mode obligations discovered by the independent PHP, Python, Rust, Workflow, and Server audits: suppress query/update plaintext shadows and raw fallbacks; refuse unsupported paths before existing codec/upload hooks; distinguish embedded, runtime, and native external references; and treat external object bytes as the 228 ASCII bytes of canonical base64, not the 169 decoded Avro-frame bytes. The conformance tests now enforce complete five-binding mappings, corrected native/embedded anchors, plaintext-shadow closure, and exact external framing. |
|
|
Security contract/source review PASS for exact The v1 contract is now unambiguous at the security and transport boundaries:
I independently recomputed the The current required-check failure is the already-tracked retired PHP setup asset ( |



Addresses the v1 contract prerequisite in #217. SDK, Workflow and Server implementation remains separate unfinished work.
This records the accepted v1 envelope and AAD decisions as a reviewable conformance contract:
This PR performs no runtime encryption, key-provider operation, package release, or live effect.
Local verification: