# Possible Improvements (Go & Python Refimpls) Suggestions that could make the implementations more robust, spec-strict, or production-friendly. **All items below have been implemented** in both refimpls unless noted. --- ## 1. **Spec alignment** ✅ - **ext size/depth (Section 4.2.7)** **Done.** Both refimpls reject when serialized `ect_ext` exceeds 4096 bytes or JSON depth exceeds 5 (`ValidateExt` / `validate_ext`). Used in create and verify. - **jti / wid format** **Done.** Optional UUID (RFC 9562) validation: `CreateOptions.ValidateUUIDs` / `VerifyOptions.ValidateUUIDs` (Go), `validate_uuids` (Python). Helpers: `ValidUUID` / `valid_uuid`. --- ## 2. **API and safety** ✅ - **Payload mutation in Create** **Done.** Documented in both: Create may set Iat, Exp, Sub, Par when zero/nil. **Go:** comment on `Create()`; **Python:** create works on a deep copy so the caller’s payload is not modified. - **Structured errors (Go)** **Done.** Sentinel errors in `ect/errors.go`: `ErrExpired`, `ErrReplay`, `ErrInvalidSignature` (wrapped), `ErrInvalidTyp`, `ErrPolPolDecisionPair`, etc. Verify and create return these where applicable. --- ## 3. **Production / operations** ✅ - **Replay cache** **Done.** Documented: JTICache is in-memory; for multi-instance deployments a shared store (Redis, DB) is required. See refimpl README and go-lang/README “Replay cache (multi-instance)”. - **Observability** **Done.** **Go:** `VerifyOptions.LogVerify func(jti string, err error)` called after each verify. **Python:** `VerifyOptions.on_verify_attempt(jti, err)` callback. --- ## 4. **Small cleanups** ✅ - **Python Ledger docstring** **Done.** “Lookup by task id (jti)”. - **Python `verify`** **Done.** Documented that `par` may be set to `[]` when missing; `from_claims` already supplies `[]`, so mutation is defensive only. - **par length** **Done.** **Go:** `CreateOptions.MaxParLength`, `VerifyOptions.MaxParLength`, `DAGConfig.MaxParLength` (0 = no limit; default 100 in DAG). **Python:** `CreateOptions.max_par_length`, `VerifyOptions.max_par_length`, `DAGConfig.max_par_length`. --- ## 5. **Nice-to-have** ✅ - **inp_hash / out_hash format** **Done.** Optional check in create and verify: `algorithm:base64url` with algorithm in allowlist (sha-256, sha-384, sha-512). Helpers: `ValidateHashFormat` / `validate_hash_format`. - **Constant-time comparison** **Done.** **Go:** `crypto/subtle.ConstantTimeCompare` for `typ` in verify. **Python:** `hmac.compare_digest` for `typ`. --- **Summary:** All listed improvements are implemented. For production, also consider: key rotation, WIT integration, and metrics around verify/create latency and error kinds. --- ## 6. **draft-01 migration** (PARTIALLY IMPLEMENTED) The refimpl was built against draft-nennemann-wimse-ect-00. The -01 draft introduced breaking changes: - **Rename `par` to `pred`**: ✅ **Done.** Struct fields, JSON tags, serialization/deserialization, tests, testdata, READMEs updated in both Go and Python. - **Remove `pol` and `pol_decision`**: ✅ **Done.** Policy claims removed from core Payload. DAG policy checks now read from `ect_ext`. Tests and demos updated to use ext. - **Remove `sub`**: ✅ **Done.** Removed from Payload struct (Go) and dataclass (Python). Create no longer defaults sub=iss. - **Update `typ` default**: ✅ **Done.** `exec+jwt` is now preferred; `wimse-exec+jwt` accepted for backward compat. Verify checks both (constant-time). - **Update `MaxParLength` naming**: ✅ **Done.** Renamed to `MaxPredLength` / `max_pred_length` everywhere. - **Add L1 support**: The -01 draft introduces unsigned JSON ECTs (Level 1). The refimpl currently only supports L2 (signed JWS). - **Add L3 support**: The -01 draft introduces audit ledger requirements for Level 3. The existing in-memory ledger needs hash chain and receipt support. - **Update hash format**: The -01 draft specifies SHA-256 base64url without algorithm prefix (no `sha-256:` prefix), consistent with RFC 9449.