Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ repository still gets a decision, never by following the link; no release carrie

### Documentation
- :memo: docs(changelog): stamp the v0.3.0 section after tagging
- :memo: docs(spec): decompose the 2026-08-18 audit Next wave as epic P5-AUD2 (D-152)

### Fixes
- :bug: docs(decisions): reference the AUD2 spec as a path, not an mkdocs link
## [0.3.0] - 2026-08-18

### Chores
Expand Down
1 change: 1 addition & 0 deletions docs/decisions/decisions.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,4 @@ project/process decisions.
| D-149 | 2026-08-16 | **OQ-1 / D-031's apiVersion rename is SUSPENDED pending the operator's in-flight brokered purchase of `assent.dev`.** The shipped schemas already carry `apiVersion: assent.dev/v1alpha1` and `$id: https://assent.dev/schemas/...`; D-028 recorded `assent.dev` as third-party-owned, and D-031 ratified Path A (register an owned domain) as the fix. The operator has since initiated a brokered transfer of `assent.dev` itself via GoDaddy — not yet closed. If it completes, D-028's premise is void and the already-shipped string is correct: **zero adopter migration.** Registering and cutting to a fallback domain now would risk a breaking `apiVersion` change for v0.1.0/v0.2.0 adopters that turns out to have been unnecessary. **Named fallback, only if the transfer fails: `assent.platformrelay.dev/v1alpha1`** — a portfolio-wide domain (`platformrelay.dev`) rather than a fresh `assent-*` registration, so the group string is settled once for every future PlatformRelay repo rather than re-litigated per project. **Checkpoint:** re-visit this row at the next handover if the transfer has neither closed nor visibly failed, so it cannot rot silently. Revert: register the fallback domain immediately and cut over — abandons the free outcome without waiting for its resolution. |
| D-150 | 2026-08-16 | **SONAR-GO-CX-TEST is RESOLVED: adopt a checked-in `sonar-project.properties` excluding `**/*_test.go` from the S3776 cognitive-complexity rule, accepting the loss of SonarCloud Automatic Analysis.** 66 CODE_SMELL issues, concentrated in 34 table-driven Go test files, against a Quality Gate that is otherwise OK (0 bugs/vulns/hotspots) — high cognitive complexity is the idiom in table-driven Go tests, not a defect. Chosen over the UI-only Won't-Fix route (keeps Automatic Analysis, but the suppression is not reviewable in-tree and does not survive a project re-import) and over refactoring the 34 files (churn on passing tests for a non-gating metric). Accepted cost: a scanner step must be added to CI and maintained going forward — Automatic Analysis stops once a `sonar-project.properties` is present. Revert: delete the properties file to restore Automatic Analysis; the 66 smells return. |
| D-151 | 2026-08-16 | **OpenSSF Best Practices project creation is RESOLVED: (a) — the operator will create the `bestpractices.dev` project for `PlatformRelay/assent`.** Unblocks SEC-SC-S02 (evidence page + README badge, once *passing*); SEC-SC-S01 (fuzzing) is not blocked by this and can proceed independently. Operator action only — requires a personal account at bestpractices.dev, not automatable in-tree. Current CII score is 0, which drags the OpenSSF Scorecard (~7); the repo already satisfies most criteria (pinned CodeQL, Dependabot, secret scanning, signed releases, SLSA provenance). Revert: leave CII at 0 indefinitely — SEC-SC-S01 is unaffected either way. |
| D-152 | 2026-08-18 | **The 2026-08-18 audit's "Next (risk reduction)" wave is decomposed as its own epic P5-AUD2 (`openspec/specs/p5-aud2-audit-remediation/spec.md`), five stories, spec-first.** Context: `agent-context/PROJECT-AUDIT-2026-08-18.md` closed both P1 conditions the same day and v0.3.0 shipped, leaving a named but untracked wave — exec-transport trio (REL-01/02/07), REL-03 `ErrNotFound` discrimination, SEC-03 cosign identity pin, TEST-02 mutant. Options considered: **(a)** hand-fix them as loose commits (rejected — AGENTS.md rule 4 is spec-first, and REL-01 is now byte-identical across *three* audits precisely because nothing ever tracked it); **(b)** append them to the existing P5-AUD epic (rejected — that epic's exit gate is CLOSED and reopening it would make "AUD complete" a moving claim); **(c)** a new AUD2 epic keyed to this audit **(chosen)**. Three consequences recorded here so they are not re-litigated: **(1)** AUD2 has **no release-condition story** — the audit had exactly two P1s and both are already closed; **(2)** **WG-S01 is deliberately excluded** — it carries the LGTM governance marker, and GOVERNANCE says such stories are surfaced to the maintainer, which an autonomous loop's decide-and-log does not override; **(3)** AUD2's exit gate is a **`task check` stage**, not a `release-exitgate` step, because that job is `pull_request`-skipped (RELSE-08) and wiring the gate there is how AUD-S18's own stale `CHECK_STAGES` pin survived four merges. A 2026-08-10-keyed AUD2 draft exists only in the local stash `leave-aud2-not-this-epic`, was never committed, and is superseded; its still-open items (F3/F5/F7) stay Later-wave. Revert: delete the spec + backlog section; the four findings return to the audit report untracked. |
40 changes: 40 additions & 0 deletions openspec/specs/backlog.md
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,46 @@ row. **Escalates back to P1 if unlanded at the next tag after v0.2.0's successor
| --- | --- | --- | --- | --- |
| WG-S01 | ⚠️ D-145: load covering profile on the run path; refuse `forge.Reconcile` when `WriteAllowed=false`; remove the docs stopgap annotation | **[autonomous · engine-grade · LGTM]** | spec-first proposal | published safety guarantee becomes true; verification target = zero forge writes against the fake under a `writes: false` profile (shape: `run_self_vouch_test.go`) |

## Phase 5 — AUD2 audit remediation (2026-08-18) — the risk-reduction wave

Full INVEST stories in [p5-aud2-audit-remediation/spec.md](p5-aud2-audit-remediation/spec.md).
AUD2 is the **"Next (risk reduction)" wave** named by
`agent-context/PROJECT-AUDIT-2026-08-18.md`. That audit's two P1 conditions (RELSE-01 changelog
regen, SEC-01 `toolchain go1.26.6`) were closed the same day and **v0.3.0 shipped** — so AUD2
carries **no release-condition story**, and that is a statement about the audit, not an omission.

Every story closes a finding the audit stated **together with its own verification recipe**;
those recipes are the `Verify:` lines in the spec, not invented ones. Three of the four findings
exist because a passing suite did not notice them (REL-01 is byte-identical across three
audits; TEST-02 is a mutation the auditor **demonstrated survives** every wired gate), so each
story's DoD names the mutation that must redden.

**Not claimed here:** the Later (hygiene) wave — TEST-01/03/04/05/06, SEC-04/05/06/07,
RELSE-03/04, ARCH-02/03/05, REL-04/05/06, DOC-02..06 — and **WG-S01**, which carries the
**LGTM** governance marker and is surfaced to the maintainer rather than auto-merged.

| ID | Story | Execution | Depends on | Gate contribution |
| --- | --- | --- | --- | --- |
| AUD2-S01 | REL-01/02/07: exec transport trio — bound stdout at `MaxResponseBytes`, `WaitDelay`, capture stderr | **[autonomous]** | none | closes the exec/HTTP containment asymmetry; a wedged provider cannot outlive its deadline |
| AUD2-S02 | ⚠️ REL-03: `errors.Is(err, forge.ErrNotFound)` discrimination on the provider-declaration fetch (D-130's sibling call site) | **[autonomous · engine-grade]** | none | a forge blip or token-scope misconfig can no longer masquerade as an absent declaration |
| AUD2-S03 | SEC-03: pin cosign signer identity + OIDC issuer in `hack/install.sh`, with a `SECURITY.md` drift gate | **[autonomous]** | none | `--require-signature` becomes a real guarantee, not a passing no-op |
| AUD2-S04 | TEST-02: kill the demonstrated `EffectChallenge` mutant (unit case + comparison-corpus entry) | **[autonomous]** | none | a wired gate reddens on the mutation the auditor proved survives |
| AUD2-S05 | Exit gate: S01–S04 dispositioned, wired **PR-visibly** into `task check` + `CHECK_STAGES` | **[autonomous]** | S01–S04 | **the AUD2 exit gate**; the RELSE-08 blind spot is not reproduced |

**Dependency order**: {S01 ∥ S02 ∥ S03 ∥ S04} — fully parallel, file-disjoint — → **S05**.
Path ownership is tabled in the spec. **`CHANGELOG.md` and this file's AUD2 status column are
Integrator-owned, not implementer-owned**: the changelog is regenerated *after* the final rebase
(rebasing rewrites the SHAs `task changelog-write` reads), and per-lane edits to it reddened
`main` twice in three days.

> ⚠️ **S05 must not be wired the way AUD-S18 was.** The `release-exitgate` job carries
> `if: github.event_name != 'pull_request'` (RELSE-08), so a gate wired only there is invisible
> to every PR — which is exactly how AUD-S18's own stale `CHECK_STAGES` pin survived four merges
> (INBOX 2026-08-16). AUD2's gate is a `task check` stage, and the **same commit** adds it to
> `CHECK_STAGES`.

**AUD2 status: SPECIFIED.**

## Phases 3–5

Epic paragraphs (goal, ADR constraints, exit gate, story seeds) in
Expand Down
Loading