docs: record structural action capture hardening

This commit is contained in:
2026-08-12 08:33:06 +01:00
parent beef434a6f
commit 67699ecd03
2 changed files with 89 additions and 0 deletions
+14
View File
@@ -1402,4 +1402,18 @@ Full record in `docs/experiment-57j66.md`.
- All existing schema, prompt-builder, and utils tests pass.
- The change is backward-compatible: field is optional by default; old proposals without it behave identically to the legacy path.
---
### Experiment 57J.72 — structuralActionRequired Direct Capture in Harness
**Objective:** Confirm whether the canonical harness can report `structuralActionRequired` directly for both accepted and rejected proposals without adding API calls or changing production behaviour. **Classification: A — HARNESS-ONLY FIX VALIDATED.**
**Answer:** YES. The field is available as a top-level property on the Update response (`updateResult.json.structuralActionRequired`) for accepted proposals, and within the rejected proposal diagnostic snapshot (`diagnostics.rejectedProposalSnapshot.structuralActionRequired`) for rejected ones.
**Fix:** Added direct capture to `scripts/reproduce-multi-turn-investigation.mjs` (accepted path prints `structuralActionRequired: true|false|null`; rejected path captures from snapshot or reports `UNAVAILABLE`). Added 12 deterministic harness tests covering all field states (true, false, null/absent for accepted; true, false, missing for rejected) plus preservation of existing answerMeaning/mutation/graph capture and no-retry call accounting. All 29 tests pass via mocked responses only. Zero Ollama calls. Zero production code changes.
**What this removes:** The need to infer `structuralActionRequired` from acceptance + meaningful mutation (the pattern used in 57J.71). Future experiments can read the field directly.
---
New branch: `feature/semantic-action-contract-v0.23`
+75
View File
@@ -0,0 +1,75 @@
# Experiment 57J.72 — structuralActionRequired Direct Capture in Harness
**Branch:** `feature/semantic-action-contract-v0.23`
**Starting HEAD:** `fc06ff0` (experiment: rerun structural action contract live)
**Experiment commit:** `beef434` (tooling: capture structural action declaration in live harness)
## Objective
Answer exactly:
> Can the canonical harness report `structuralActionRequired` directly for both accepted and rejected update proposals without adding any API calls or changing production behaviour?
## Answer
**YES.** The field is available as a top-level property on the Update response (`updateResult.json.structuralActionRequired`) for accepted proposals, and within the rejected proposal diagnostic snapshot (`diagnostics.rejectedProposalSnapshot.structuralActionRequired`) for rejected ones. The harness can capture both without any additional calls or production changes.
## Changes Made
### Harness (`scripts/reproduce-multi-turn-investigation.mjs`)
**Accepted update path** (line ~132): Added direct capture of `updateResult.json.structuralActionRequired`, printing:
- `structuralActionRequired: <true|false>` when the field is present and truthy/falsy
- `structuralActionRequired: null` when absent or explicitly null
No inference from HTTP status, mutation arrays, or validator outcome.
**Rejected update path** (line ~91): Added capture from `diagnostics.rejectedProposalSnapshot.structuralActionRequired`, printing:
- `structuralActionRequired (from rejected proposal snapshot): <true|false>` when the field exists in the snapshot
- `structuralActionRequired: UNAVAILABLE` when the field is absent
### Harness Tests (`tests/reproduce-multi-turn-investigation.harness.test.js`)
Added 12 new deterministic tests (mocked responses only, zero Ollama calls):
1. accepted update with `structuralActionRequired=true` reports `true`;
2. accepted update with `structuralActionRequired=false` reports `false`;
3. accepted update with absent field reports `null`;
4. accepted update with explicit null reports `null`;
5. rejected snapshot with `structuralActionRequired=true` captures true;
6. rejected snapshot with `structuralActionRequired=false` captures false;
7. rejected snapshot without the field confirms absence (would print UNAVAILABLE);
8. existing answerMeaning capture unchanged;
9. existing mutation/persistent-graph capture unchanged;
10. no extra HTTP calls introduced;
11. no-retry and call accounting preserved across both paths.
## Call Accounting
- startCalls: 0 (harness-only change)
- updateCalls: 0 (no new API calls)
- Additional diagnostic calls: 0
- Total additional live calls: 0
## Production Code Changed
**NO.** Only harness capture added to the observable output layer. The production `updateCase()` response shape already includes `structuralActionRequired` as a top-level field (confirmed by experiment 57J.69 and 57J.71 observations).
## Prompt / Schema / Validator Changes
None. This is purely an observability hardening of the harness.
## Test Results
**29 tests pass** (17 existing + 12 new) via mocked responses only.
## Classification: A — HARNESS-ONLY FIX VALIDATED
The canonical harness can now directly report `structuralActionRequired` for both accepted and rejected updates without any inference, no additional API calls, and zero production code changes. This removes the need to infer the field from acceptance + meaningful mutation (the pattern used in 57J.71).
## Dependencies Preserved
- 57J.62 capture hardening (accepted-update console block structure)
- 57J.70 authoritative guard (validator in lib/graph/utils.js)
- Exact call accounting invariant
- No-retry contract for rejected updates