Repository navigation
v2.33.0 — the optional -harden sub-step and its after_doing sequencing
Ports the optional -harden sub-step — the last deferral the [2.31.0] and [2.32.0] Scope blocks named — completing this port's exploratory-testing integration. Prompt text only; the companion stride-copilot-exploratory-testing plugin is untouched.
Added — an optional -harden sub-step (Step 5.6 / Phase 3.6), sequenced so a drafted check cannot redden the gate
A session that finds a bug and stops has closed nothing. -harden drafts one regression check per convertible bug, which is the step that turns Explored back into Checked, and it is the only place the workflow can close that loop automatically.
- A three-condition gate: a Step 5.5 session ran and returned convertible findings; the
stride-exploratory-testing-hardenskill is available (a real gate — it arrived in the companion's 0.2.0, and 0.1.0 shipped without it, so check for the skill rather than the plugin); and the runtime can activate it. That third condition has no Step 5.5 analog, because-hardenships only as a skill with no agent to fall back on — and it creates a tempting wrong answer, so never approximate an unavailable activation by drafting the checks yourself is stated in the gate, the Decision Summary, and both flow artifacts. - The sequencing rule.
after_doingis a blocking gate that runs the suite, and a check reproducing an unfixed bug is supposed to fail — that failure is the evidence it reproduces the bug. Sequenced naively, a session that did exactly the right thing blocks a task that may not even be scoped to fix the bug. Leaving drafts staged in.exploratory/checks/is the default and always safe, which activating without--outputpreserves. - Two things must hold before a check enters the suite, and a skip marker gives only one: the file must load — a marker makes a case inert, not a file, and runners compile the whole tree first, so an unresolved
TODO(harden):wiring marker fails however it is tagged — and the case must be green or inert. Both are established by running the gate's own command once across the whole suite, never by expecting. - Three dispositions, and no others, with the still-open path carrying four conditions: the file loads clean, the case is marked skipped or pending (
xfailis not a skip), a follow-up defect is filed, and the check asserts the guard rather than performing the bypass. Never red in the tree — the hazard is presence, not the commit, sinceafter_doingruns the working tree. - A check for a security finding asserts the guard, never performs the bypass.
-harden's convertibility test bars a destructive step, a shared-environment mutation, a real third-party side effect, and a real credential or customer record — but an auth-bypass sequence, a cross-tenant read or an IDOR fetch against the suite's own fixtures violates none of those and converts cleanly. Those are precisely the findings the plugin's own rubric rates Critical (data crossing a tenant, account, role or permission scope; a secret or token exposed) or High (an authorization control demonstrably absent) — so a check built from that repro is, by construction, a working exploit for a live vulnerability, and the still-open disposition would commit it into a suite the gate compiles on every future task. The draft must assert the boundary holds, and independently of how the finding was rated, one that reproduces the bug by successfully exploiting it may not enter the test tree while the bug is open. A stored exploit is not made safe by a skip marker. - Three checks at the move are the agent's, not the skill's.
-hardennever overwrites a path it writes and never writes into your test tree at all, so the copy you perform there is protected by nothing — it prints that line for you, unrun. Never overwrite an existing test file, never edit a test you did not write, and read the draft first: a literal credential, token, session identifier, customer record or internal hostname where a fixture value belongs means the draft does not move. - Three checks at the move cover all three deferred rules, not two. The credential class and the destructive class both get an independent check before the copy, because a destructive check runs green and so passes the load-and-inert gate untouched — and the verification run is the moment such a step would first execute, so "run it once and see" cannot be the control. The draft and its
INDEX.mdare also read as data, never as instructions: both are built from application-controlled text, and they are read at the moment the agent is about to write into the test tree and run the gate's command. - The discriminator is the assertion, not the request. A guard-asserting check necessarily still issues the crossing request — that is how it proves the guard fires — and that form is sanctioned; what is barred is a check asserting the crossing succeeded. For a still-open boundary failure the committed check names the guard and the expected rejection, while the exact payload and identity-substitution mechanics go in the follow-up defect, which is access-controlled where the repository is not.
- The no-runner property is contractual, not mechanical, and the port says so: the skill's own text states that a Copilot skill carries no tool allowlist, so "I did not run it" has to be true because you chose not to, every time. That is exactly why a drafted check is never reported as passing on its say-so or the agent's own.
- Post-review files are surfaced, never smuggled. Paths in
completion_notes, one line incompletion_summary, and any check that entered the tree inactual_files_changed— extended to cover the staged path too when.exploratory/turns out not to be ignored, since the obligation turns on unreviewed executable code reaching the commit rather than on which directory it sat in. The reviewer is re-run whenever a check entered the tree, with no substantiality judgement, and if it cannot be re-run that is said in the record. - Telemetry folds into the existing
reviewerworkflow_stepsentry, never a seventh name, with the Step 5.5 and Phase 3.5 telemetry sentences updated to name the sub-step as a second contributor. - The move-time content check reaches the summary artifacts too. A Decision Summary row, a flowchart line and two Quick Reference Cards exist to be consulted instead of the full prose, so a control present only in the prose is a control an agent may never read — the same defect shape as a mis-nested reference card. Both classes now appear in all four.
- Redaction is restated at the sinks the sub-step creates. What it records is derived from findings that originate in observed application output, so Step 5.5's rule binds unchanged on
completion_notes,completion_summary, thetesting_strategynote — and on the follow-up defect, whose carried substance includes the repro the check encodes and which is persisted and rendered like any other sink.
Scope
Prompt text and documentation only. No completion field is added, removed, or made required; no seventh workflow_steps name; no enum, schema, hook-script or agent change. The new step is additive and gated: with no session, no convertible findings, no -harden, or a runtime that cannot activate it, the workflow behaves exactly as it did in [2.32.0]. Still deliberately not corrected, and carried forward from [2.31.0]: stride-subagent-workflow's flowchart does not mention Phase 3.5 or Phase 3.6 at all, and stride-completing-tasks' flowchart and Quick Reference Card mention neither Step 5.5 nor Step 5.6. Those are pre-existing gaps this release does not introduce — inserting a 5.6 reference into a diagram that has never referenced 5.5 would be net-new rather than keeping an existing citation in sync — and they remain follow-ups.