Expired-cert signing: WORKS with warning (old-cert.p12 is expired 2026-03-29) #40

Closed
opened 2026-10-15 01:19:20 +02:00 by EduarD3V · 78 comments
Owner

Goal

The real legacy keystore work/certs/old-cert.p12 holds an FNMT cert that EXPIRED 2026-03-29. AutoFirma-equivalent behavior: signing must still SUCCEED but the app must clearly WARN.

Secrets (HARD RULES)

Same as standing rules: work/certs/*.p12 gitignored, PIN in .p12pass runtime-read, never printed/committed.

Tasks

  1. Cert-load path: detect notAfter < now ⇒ mark cert entry expired: true; UI shows amber warning banner (cert expired on ) but does NOT block signing.
  2. Verify path: when verifying a signature whose signer cert is expired ⇒ result valid-but-expired distinct state (signature cryptographically valid, cert outside validity window) with visible warning.
  3. Tests: synthetic expired cert fixture (generate at test time, no binaries); real old-cert.p12 used by smoke script when present (skip otherwise).
  4. scripts/smoke-real.sh: default cert = old-cert.p12 must still exit 0 with the warning surfaced in output.

Gates

pnpm test green, build clean, smoke-real.sh exit 0 (warning shown, signature produced+verified).

Ownership

Owns certstore/certpicker warning UI + verify result state. Do NOT touch pades signing internals (separate issues own those).

## Goal The real legacy keystore `work/certs/old-cert.p12` holds an FNMT cert that EXPIRED 2026-03-29. AutoFirma-equivalent behavior: signing must still SUCCEED but the app must clearly WARN. ## Secrets (HARD RULES) Same as standing rules: `work/certs/*.p12` gitignored, PIN in `.p12pass` runtime-read, never printed/committed. ## Tasks 1. Cert-load path: detect notAfter < now ⇒ mark cert entry `expired: true`; UI shows amber warning banner (cert expired on <date>) but does NOT block signing. 2. Verify path: when verifying a signature whose signer cert is expired ⇒ result `valid-but-expired` distinct state (signature cryptographically valid, cert outside validity window) with visible warning. 3. Tests: synthetic expired cert fixture (generate at test time, no binaries); real old-cert.p12 used by smoke script when present (skip otherwise). 4. `scripts/smoke-real.sh`: default cert = old-cert.p12 must still exit 0 with the warning surfaced in output. ## Gates pnpm test green, build clean, smoke-real.sh exit 0 (warning shown, signature produced+verified). ## Ownership Owns certstore/certpicker warning UI + verify result state. Do NOT touch pades signing internals (separate issues own those).
Author
Owner

bullet: coder launched on branch issue/40-expired-cert-signing-works-wit (model nan/deepseek-v4-flash).

bullet: coder launched on branch `issue/40-expired-cert-signing-works-wit` (model `nan/deepseek-v4-flash`).
Author
Owner

Claimed — branch issue/40-expired-cert-signing-works-wit. Doing: verify report gets a distinct valid-but-expired state (warn, not fail), amber expiry banner in the cert picker, synthetic expired fixture + real old-cert.p12 smoke script. Note: the BULLET_TOKEN I was handed is scoped to other repos (404 on this one), so comments go through BULLET_BASIC.

Claimed — branch `issue/40-expired-cert-signing-works-wit`. Doing: verify report gets a distinct `valid-but-expired` state (warn, not fail), amber expiry banner in the cert picker, synthetic expired fixture + real old-cert.p12 smoke script. Note: the `BULLET_TOKEN` I was handed is scoped to other repos (404 on this one), so comments go through `BULLET_BASIC`.
Author
Owner

Issue #40 — Expired-cert signing: works, with a warning

Restated goal

Signing with an expired certificate must behave like AutoFirma: it succeeds, but the app says so
loudly. Two surfaces carry that:

  1. Sign path — loading work/certs/old-cert.p12 (FNMT leaf, notAfter 2026-03-29, already past)
    must mark the certificate entry expired: true and surface an amber banner naming the expiry
    date instead of the current red text, without disabling the sign button.
  2. Verify path — verifying a signature whose signer certificate is outside its validity window
    must yield a distinct valid-but-expired report state: the cryptographic checks pass, the
    certValidity check warns instead of failing, and the report UI shows a visible amber warning.
    The report must not be reported as invalid (ok stays true) when the only problem is expiry.

"Done" = pnpm test green (including a synthetic expired-cert fixture generated at test time and a
real-clock expiry end-to-end test), pnpm build clean, and scripts/smoke-real.sh exiting 0 with
the warning printed and a signature produced + verified (openssl cms -verify cross-check plus our
own verifier reporting valid-but-expired).

Starting state (already in the branch, verified by reading)

  • SignerCert.expired / .notYetValid already set in src/lib/keystore.ts:164-165; the picker
    already prints a red one-liner for cert?.expired (no date, destructive colour).
  • src/lib/verify/{cms,xades}.ts currently push certValidity as fail when out of window,
    which flips report.ok to false — the bug this issue fixes.
  • scripts/smoke-real.sh does not exist; work/ is absent from this worktree.

Scope

Will change

File Change
src/lib/verify/types.ts CheckStatus + 'warn'; add VerificationStatus = 'valid' | 'valid-but-expired' | 'invalid', VerificationReport.status, and a summarize(checks, expired) helper
src/lib/verify/cms.ts signer validity → warn when outside the window, report status from summarize
src/lib/verify/xades.ts same
src/lib/verify/index.ts non-signature reports get status: 'invalid'
src/lib/components/VerifyReport.svelte three-way banner (invalid red / valid-but-expired amber / valid green) + warn card style
src/lib/components/CertPicker.svelte amber alert with the expiry date for an expired signer; amber expiry line on expired stored identities
src/lib/i18n.ts verifyExpired (ES/EN); expiry-date wording for the picker banner
src/test/fixtures.ts expired PKCS#12 fixture generated with openssl req -x509 -not_after <past> (no committed binary)
src/lib/pkcs12.test.ts load the expired fixture → expired: true, key present, signing still works
src/lib/verify.test.ts signature made with the expired fixture, verified at the real clock → status === 'valid-but-expired', certValidity === 'warn', signature === 'pass', ok === true; CAdES + XAdES
src/lib/real-cert.test.ts new: real old-cert.p12 end-to-end (skip when cert/PIN absent), target of the smoke script
scripts/smoke-real.sh new: default work/certs/old-cert.p12, exit 0 with the warning surfaced

Will not touch — src/lib/pades.ts, src/lib/pkcs12.ts internals, the PAdES/CAdES/XAdES
builders apart from using them, src/lib/certstore.ts sealing, mcp/, docs/MCP-DESIGN.md,
Containerfile, the trust store under src/lib/verify/roots.

Ordered tasks (each with its verifying command)

  1. Types + verifier state. types.ts, verify/cms.ts, verify/xades.ts, verify/index.ts.
    Verify: pnpm vitest run src/lib/verify.test.ts (existing tests unchanged and green).
  2. UI. VerifyReport.svelte, CertPicker.svelte, i18n.ts.
    Verify: pnpm vitest run src/lib/components/CertPicker.test.ts src/lib/App.test.ts.
  3. Synthetic expired fixture + tests. src/test/fixtures.ts, pkcs12.test.ts, verify.test.ts.
    Verify: pnpm vitest run src/lib/pkcs12.test.ts src/lib/verify.test.ts.
  4. Real-cert smoke. src/lib/real-cert.test.ts, scripts/smoke-real.sh.
    Verify: bash scripts/smoke-real.sh → exit 0, warning line printed (with the cert copied into the
    worktree's gitignored work/certs/; script skips cleanly when absent).
  5. Gates. pnpm test, pnpm build, git diff --check, bash scripts/smoke-real.sh.
  6. Report + Done comment.

Commits after each verified task: <area>: <what changed> (Refs #40).

Open questions (assumption taken, no human to ask)

  • Should ok remain true for an expired signer? Assumed yes: the signature is cryptographically
    valid and AutoFirma does not reject it; the distinct status field carries the nuance. ok is
    derived from status (ok === status !== 'invalid') so the two can never disagree.
  • Not-yet-valid certificates? The issue only names expiry. The certValidity check warns for
    either side of the window, but status: 'valid-but-expired' is only produced when notAfter is in
    the past; a not-yet-valid signer stays valid with the warn check visible.
  • Where does the real cert live? work/certs/*.p12 is gitignored and absent from this worktree.
    The smoke script and the integration test resolve it relative to the repo root and skip with exit
    0
    when missing, as the issue asks. To run the gate here, the operator's read-only
    work/certs/old-cert.p12 + .p12pass are copied into this worktree's gitignored work/ — nothing
    outside this worktree is modified.
  • PIN handling. .p12pass is read at runtime into an env var and never echoed, committed or
    printed — including in failure output.

Risk and boring fallback

  • Risk: adding warn to CheckStatus breaks exhaustive maps (VerifyReport.svelte styles) or
    the report type. Fallback: keep CheckStatus untouched and express the state only through
    report.status + an info check — worse UI, same behaviour.
  • Risk: openssl -not_after unavailable on another machine's OpenSSL. Fallback: the existing
    { now } clock override in loadSignerSession still expresses the expired case; the fixture helper
    keeps working on OpenSSL 3.4+ only, and the test says so in its failure message.
  • Risk: real-cert smoke cannot run here (no cert in the worktree). Fallback: the script's own
    skip path is verified by running it once without the cert, and the report says exactly which gate
    was proven against the real container and which was only exercised through fixtures.
# Issue #40 — Expired-cert signing: works, with a warning ## Restated goal Signing with an expired certificate must behave like AutoFirma: it **succeeds**, but the app says so loudly. Two surfaces carry that: 1. **Sign path** — loading `work/certs/old-cert.p12` (FNMT leaf, `notAfter` 2026-03-29, already past) must mark the certificate entry `expired: true` and surface an **amber** banner naming the expiry date instead of the current red text, without disabling the sign button. 2. **Verify path** — verifying a signature whose signer certificate is outside its validity window must yield a **distinct `valid-but-expired`** report state: the cryptographic checks pass, the `certValidity` check warns instead of failing, and the report UI shows a visible amber warning. The report must not be reported as invalid (`ok` stays true) when the only problem is expiry. "Done" = `pnpm test` green (including a synthetic expired-cert fixture generated at test time and a real-clock expiry end-to-end test), `pnpm build` clean, and `scripts/smoke-real.sh` exiting 0 with the warning printed and a signature produced + verified (openssl `cms -verify` cross-check plus our own verifier reporting `valid-but-expired`). ## Starting state (already in the branch, verified by reading) - `SignerCert.expired` / `.notYetValid` already set in `src/lib/keystore.ts:164-165`; the picker already prints a red one-liner for `cert?.expired` (no date, destructive colour). - `src/lib/verify/{cms,xades}.ts` currently push `certValidity` as **`fail`** when out of window, which flips `report.ok` to false — the bug this issue fixes. - `scripts/smoke-real.sh` does **not** exist; `work/` is absent from this worktree. ## Scope **Will change** | File | Change | |---|---| | `src/lib/verify/types.ts` | `CheckStatus` + `'warn'`; add `VerificationStatus = 'valid' \| 'valid-but-expired' \| 'invalid'`, `VerificationReport.status`, and a `summarize(checks, expired)` helper | | `src/lib/verify/cms.ts` | signer validity → `warn` when outside the window, report `status` from `summarize` | | `src/lib/verify/xades.ts` | same | | `src/lib/verify/index.ts` | non-signature reports get `status: 'invalid'` | | `src/lib/components/VerifyReport.svelte` | three-way banner (invalid red / `valid-but-expired` amber / valid green) + warn card style | | `src/lib/components/CertPicker.svelte` | amber alert with the expiry date for an expired signer; amber expiry line on expired stored identities | | `src/lib/i18n.ts` | `verifyExpired` (ES/EN); expiry-date wording for the picker banner | | `src/test/fixtures.ts` | `expired` PKCS#12 fixture generated with `openssl req -x509 -not_after <past>` (no committed binary) | | `src/lib/pkcs12.test.ts` | load the expired fixture → `expired: true`, key present, signing still works | | `src/lib/verify.test.ts` | signature made with the expired fixture, verified at the **real clock** → `status === 'valid-but-expired'`, `certValidity === 'warn'`, `signature === 'pass'`, `ok === true`; CAdES + XAdES | | `src/lib/real-cert.test.ts` | **new**: real `old-cert.p12` end-to-end (skip when cert/PIN absent), target of the smoke script | | `scripts/smoke-real.sh` | **new**: default `work/certs/old-cert.p12`, exit 0 with the warning surfaced | **Will not touch** — `src/lib/pades.ts`, `src/lib/pkcs12.ts` internals, the PAdES/CAdES/XAdES *builders* apart from using them, `src/lib/certstore.ts` sealing, `mcp/`, `docs/MCP-DESIGN.md`, `Containerfile`, the trust store under `src/lib/verify/roots`. ## Ordered tasks (each with its verifying command) 1. **Types + verifier state.** `types.ts`, `verify/cms.ts`, `verify/xades.ts`, `verify/index.ts`. Verify: `pnpm vitest run src/lib/verify.test.ts` (existing tests unchanged and green). 2. **UI.** `VerifyReport.svelte`, `CertPicker.svelte`, `i18n.ts`. Verify: `pnpm vitest run src/lib/components/CertPicker.test.ts src/lib/App.test.ts`. 3. **Synthetic expired fixture + tests.** `src/test/fixtures.ts`, `pkcs12.test.ts`, `verify.test.ts`. Verify: `pnpm vitest run src/lib/pkcs12.test.ts src/lib/verify.test.ts`. 4. **Real-cert smoke.** `src/lib/real-cert.test.ts`, `scripts/smoke-real.sh`. Verify: `bash scripts/smoke-real.sh` → exit 0, warning line printed (with the cert copied into the worktree's gitignored `work/certs/`; script skips cleanly when absent). 5. **Gates.** `pnpm test`, `pnpm build`, `git diff --check`, `bash scripts/smoke-real.sh`. 6. **Report + Done comment.** Commits after each verified task: `<area>: <what changed> (Refs #40)`. ## Open questions (assumption taken, no human to ask) - **Should `ok` remain true for an expired signer?** Assumed yes: the signature is cryptographically valid and AutoFirma does not reject it; the distinct `status` field carries the nuance. `ok` is derived from `status` (`ok === status !== 'invalid'`) so the two can never disagree. - **Not-yet-valid certificates?** The issue only names expiry. The `certValidity` check warns for either side of the window, but `status: 'valid-but-expired'` is only produced when `notAfter` is in the past; a not-yet-valid signer stays `valid` with the warn check visible. - **Where does the real cert live?** `work/certs/*.p12` is gitignored and absent from this worktree. The smoke script and the integration test resolve it relative to the repo root and **skip with exit 0** when missing, as the issue asks. To run the gate here, the operator's read-only `work/certs/old-cert.p12` + `.p12pass` are copied into this worktree's gitignored `work/` — nothing outside this worktree is modified. - **PIN handling.** `.p12pass` is read at runtime into an env var and never echoed, committed or printed — including in failure output. ## Risk and boring fallback - **Risk:** adding `warn` to `CheckStatus` breaks exhaustive maps (`VerifyReport.svelte` styles) or the report type. *Fallback:* keep `CheckStatus` untouched and express the state only through `report.status` + an `info` check — worse UI, same behaviour. - **Risk:** `openssl -not_after` unavailable on another machine's OpenSSL. *Fallback:* the existing `{ now }` clock override in `loadSignerSession` still expresses the expired case; the fixture helper keeps working on OpenSSL 3.4+ only, and the test says so in its failure message. - **Risk:** real-cert smoke cannot run here (no cert in the worktree). *Fallback:* the script's own skip path is verified by running it once without the cert, and the report says exactly which gate was proven against the real container and which was only exercised through fixtures.
Author
Owner

DONE — branch issue/40-expired-cert-signing-works-wit, commits 989f6978 ec631ada 13dc5217 f0e785bf 163c5d69.

Gates (all on HEAD 163c5d69, tree clean):

  • pnpm test exit 0 — 17 files, 146 tests, including the real old-cert.p12 suite.
  • pnpm build exit 0 — static site written to build/.
  • git diff --check clean.
  • bash scripts/smoke-real.sh exit 0 — WARNING: GARCIA APARICIO EDUARDO - 05718264G expired 2026-03-29T06:34:25.000Z — signing anyway, openssl: CMS Verification successful, signature verified by our verifier as valid-but-expired; skips with exit 0 without the gitignored cert.
  • Browser: sign panel shows the amber alert (… Caduca: Mar 29, 2026, border-amber-600/50) with the sign button enabled; verify panel of a real XAdES signed by the expired FNMT cert shows the amber banner Firma válida, pero el certificado del firmante ha caducado. XAdES with certValidity=warn, every other check pass.

What changed: CheckStatus gains warn; the report carries status: valid|valid-but-expired|invalid derived once in summarize() so it can never disagree with ok; certValidity warns (never fails) outside the window; the verify banner is three-way; the picker warns in amber with the expiry date and does not block signing; expired PKCS#12 fixtures are generated at test time; scripts/smoke-real.sh + src/lib/real-cert.test.ts exercise the real container; README documents the verdict.

Two things for the human: (1) src/test/fixtures.ts had to be fixed to read this box's xmlsec1 1.3.12 verdict wording (Verification status: OK) — App.test.ts failed with "xmlsec1 printed no verdict" before any of my changes, one hunk, split it out if you prefer; (2) the suite is load-sensitive: during a load-13 spike two runs failed with 5 s openssl-keygen timeouts in untouched tests, all three failing files pass in isolation and the suite is green at lower load.

DONE — branch `issue/40-expired-cert-signing-works-wit`, commits `989f6978` `ec631ada` `13dc5217` `f0e785bf` `163c5d69`. Gates (all on HEAD `163c5d69`, tree clean): - `pnpm test` exit 0 — 17 files, 146 tests, including the real `old-cert.p12` suite. - `pnpm build` exit 0 — static site written to `build/`. - `git diff --check` clean. - `bash scripts/smoke-real.sh` exit 0 — `WARNING: GARCIA APARICIO EDUARDO - 05718264G expired 2026-03-29T06:34:25.000Z — signing anyway`, `openssl: CMS Verification successful`, signature verified by our verifier as `valid-but-expired`; skips with exit 0 without the gitignored cert. - Browser: sign panel shows the amber alert (`… Caduca: Mar 29, 2026`, `border-amber-600/50`) with the sign button enabled; verify panel of a real XAdES signed by the expired FNMT cert shows the amber banner `Firma válida, pero el certificado del firmante ha caducado. XAdES` with `certValidity=warn`, every other check `pass`. What changed: `CheckStatus` gains `warn`; the report carries `status: valid|valid-but-expired|invalid` derived once in `summarize()` so it can never disagree with `ok`; `certValidity` warns (never fails) outside the window; the verify banner is three-way; the picker warns in amber with the expiry date and does not block signing; expired PKCS#12 fixtures are generated at test time; `scripts/smoke-real.sh` + `src/lib/real-cert.test.ts` exercise the real container; README documents the verdict. Two things for the human: (1) `src/test/fixtures.ts` had to be fixed to read this box's xmlsec1 1.3.12 verdict wording (`Verification status: OK`) — `App.test.ts` failed with "xmlsec1 printed no verdict" before any of my changes, one hunk, split it out if you prefer; (2) the suite is load-sensitive: during a load-13 spike two runs failed with 5 s openssl-keygen timeouts in untouched tests, all three failing files pass in isolation and the suite is green at lower load.
Author
Owner

bullet: coder session died — relaunched from committed state (branch issue/40-expired-cert-signing-works-wit).

bullet: coder session died — relaunched from committed state (branch `issue/40-expired-cert-signing-works-wit`).
Author
Owner

bullet: implementation finished (DONE — branch issue/40-expired-cert-signing-works-wit, commits 989f6978 ec631ada 13dc5217 f0e785bf 163c5d69.) — moving to review.

bullet: implementation finished (DONE — branch `issue/40-expired-cert-signing-works-wit`, commits `989f6978` `ec631ada` `13dc5217` `f0e785bf` `163c5d69`.) — moving to review.
Author
Owner

Claimed — branch issue/40-expired-cert-signing-works-wit. Doing: five #40 commits already sit on this branch from an interrupted session; no plan file and the gates were never run (pnpm test red). Diagnosing the red gate, then re-verifying test/build/smoke.

Claimed — branch `issue/40-expired-cert-signing-works-wit`. Doing: five #40 commits already sit on this branch from an interrupted session; no plan file and the gates were never run (`pnpm test` red). Diagnosing the red gate, then re-verifying test/build/smoke.
Author
Owner

Plan — issue #40: expired-cert signing (works, with warning)

Restated goal

work/certs/old-cert.p12 is a real legacy FNMT keystore whose certificate expired 2026-03-29.
Signing with it must still SUCCEED, while the app says the expiry out loud in both flows:

  1. Load/sign path — a PKCS#12 certificate whose notAfter is in the past is flagged (no key
    withheld, signing not blocked), and the picker shows an amber banner with the expiry date.
  2. Verify path — a signature whose signer certificate is outside its validity window reports a
    distinct valid-but-expired verdict (signature sound, certificate past notAfter) instead of
    invalid, with a visible amber warning.
  3. Tests — a synthetic expired fixture generated at test time (no committed binaries), and the
    real container exercised by a smoke script when present (skipped otherwise).
  4. scripts/smoke-real.sh — defaulting to old-cert.p12, exits 0 with the warning surfaced in
    the output and the signature produced + verified.

Done = the four points above, pnpm test green, pnpm build clean, scripts/smoke-real.sh
exit 0, and the diff confined to the files below.

State found on arrival (important)

The branch already carries five commits from an earlier, interrupted session of this same issue —
the implementation, tests and docs of all four tasks are written and committed:

Commit What
989f6978 feat(verify): valid-but-expired verdict + warn check status
ec631ada feat(ui): amber expiry warning in CertPicker + VerifyReport
13dc5217 test: synthetic expired fixture (openssl-generated), verify coverage
f0e785bf test(smoke): src/lib/real-cert.test.ts + scripts/smoke-real.sh
163c5d69 docs: README verify-flow and script table

No plan or report file was written, and the gates were never run — pnpm test is red on
arrival (7 failures / 4 files). So this session's work is: diagnose the red gate, fix what belongs
to #40, re-verify every gate, and write the report. No re-implementation.

Scope

Files this plan may touch

Path Why
src/lib/verify.test.ts, src/lib/pkcs12.test.ts, src/lib/components/CertPicker.test.ts, src/lib/App.test.ts only if a failure is caused by #40's own change
src/test/fixtures.ts the xmlsec1Verify hunk collides with branch issue/45-…; align byte-for-byte so the integration merge is conflict-free
scripts/smoke-real.sh only if the smoke run fails
src/lib/verify/{types,cms,xades}.ts, src/lib/components/{CertPicker,VerifyReport}.svelte, src/lib/i18n.ts already committed; touched only to fix a demonstrated bug

Files deliberately NOT touched

  • PAdES internals (src/lib/pades.ts, src/lib/pades.test.ts) — owned by other issues, and the
    issue's ownership clause says so explicitly.
  • src/lib/cms.ts (the CAdES builder), src/lib/keystore.ts's crypto, src/lib/x509.ts parsing:
    the expired / notYetValid flags already exist on SignerCert (src/lib/sign.ts), which is
    what task 1 asks for. Re-adding them would be a second convention.
  • work/, original/, decompiled*/ — gitignored inputs; the container and .p12pass are read at
    runtime, never printed, never committed.
  • docs/ beyond the README rows already updated.

Ordered tasks

  1. Reproduce and attribute the red gate. pnpm test (full output, failures by file) →
    compare each failing test against git show 163c5d69 --stat to decide pre-existing vs.
    caused-by-#40. Verify: the failure list with a cause per failure recorded in the report.
  2. Fix the #40-caused failures only, at the cause (never by weakening a test).
    Verify: pnpm exec vitest run <file> for each file touched, green.
  3. Align the xmlsec1Verify hunk with issue/45 so the shared file cannot conflict at
    integration. Verify: git diff issue/45-… issue/40-… -- src/test/fixtures.ts shows no hunk
    touching xmlsec1Verify, and pnpm exec vitest run src/lib/xades.test.ts stays green.
  4. Full gates. pnpm test → green; pnpm build → clean; git diff --check → clean.
  5. Smoke. bash scripts/smoke-real.sh with the default work/certs/old-cert.p12 and the PIN
    from .p12pass; must exit 0 with WARNING: … expired … and the openssl re-verification in the
    output, and the report must assert valid-but-expired. Verify: echo $? = 0.
  6. Report. .bullet/meta/issue-40.report.md with the outcome, commit hashes, one line per gate.

Open questions (assumption stated, moving on)

  • Are the 7 failures pre-existing on main or caused by #40? Assumed mixed until task 1 shows it.
    Hard-law forbids checking out main in this worktree, so attribution is done by reading the
    failing assertions against the diff, not by a baseline run.
  • Is committing the xmlsec1Verify regex part of #40? #45 owns that change and already committed
    it. Assumption: the earlier session needed it because this box runs xmlsec1 1.3.12 (which prints
    Verification status: OK, not status: OK) and the suite is otherwise red. Keep it, but align it
    with #45's exact text so the two branches do not conflict.
  • Does anything else construct a VerificationReport? Assumption: only verify/cms.ts,
    verify/xades.ts and the error paths in verify/index.ts; status was added to all of them.
    A missed producer would be a pnpm build type error, which task 4 catches.

Risk and boring fallback

  • Risk: the failures are unrelated flakiness (jsdom/testing-library dialog timing). Fallback:
    re-run the single file in isolation; if it passes alone and fails only in the full run, report it
    as a pre-existing suite-level flake with the evidence and leave it untouched.
  • Risk: openssl req -not_before/-not_after needs OpenSSL ≥ 3.4. This box has 4.0.3, so the
    fixture works here; a contributor on 3.0 would see a fixture error. Fallback: that is already
    documented in the fixture's comment; no code change.
  • Risk: fixing the fixture-hunk alignment could break the XAdES tests. Fallback: revert to the
    current hunk (the reconciler resolves the one-line conflict) and note it in the report.
  • Budget risk. If task 2 exceeds ~15 minutes: stop, commit what is verified, and report PARTIAL
    with the exact failing command and its first error line.
# Plan — issue #40: expired-cert signing (works, with warning) ## Restated goal `work/certs/old-cert.p12` is a real legacy FNMT keystore whose certificate expired 2026-03-29. Signing with it must still SUCCEED, while the app says the expiry out loud in both flows: 1. **Load/sign path** — a PKCS#12 certificate whose `notAfter` is in the past is flagged (no key withheld, signing not blocked), and the picker shows an amber banner with the expiry date. 2. **Verify path** — a signature whose signer certificate is outside its validity window reports a distinct `valid-but-expired` verdict (signature sound, certificate past `notAfter`) instead of `invalid`, with a visible amber warning. 3. **Tests** — a synthetic expired fixture generated at test time (no committed binaries), and the real container exercised by a smoke script when present (skipped otherwise). 4. **`scripts/smoke-real.sh`** — defaulting to `old-cert.p12`, exits 0 with the warning surfaced in the output and the signature produced + verified. **Done** = the four points above, `pnpm test` green, `pnpm build` clean, `scripts/smoke-real.sh` exit 0, and the diff confined to the files below. ## State found on arrival (important) The branch already carries five commits from an earlier, interrupted session of this same issue — the implementation, tests and docs of all four tasks are written and committed: | Commit | What | |---|---| | `989f6978` | `feat(verify)`: `valid-but-expired` verdict + `warn` check status | | `ec631ada` | `feat(ui)`: amber expiry warning in CertPicker + VerifyReport | | `13dc5217` | `test`: synthetic expired fixture (openssl-generated), verify coverage | | `f0e785bf` | `test(smoke)`: `src/lib/real-cert.test.ts` + `scripts/smoke-real.sh` | | `163c5d69` | `docs`: README verify-flow and script table | No plan or report file was written, and the gates were never run — `pnpm test` is **red** on arrival (7 failures / 4 files). So this session's work is: diagnose the red gate, fix what belongs to #40, re-verify every gate, and write the report. No re-implementation. ## Scope ### Files this plan may touch | Path | Why | |---|---| | `src/lib/verify.test.ts`, `src/lib/pkcs12.test.ts`, `src/lib/components/CertPicker.test.ts`, `src/lib/App.test.ts` | only if a failure is caused by #40's own change | | `src/test/fixtures.ts` | the `xmlsec1Verify` hunk collides with branch `issue/45-…`; align byte-for-byte so the integration merge is conflict-free | | `scripts/smoke-real.sh` | only if the smoke run fails | | `src/lib/verify/{types,cms,xades}.ts`, `src/lib/components/{CertPicker,VerifyReport}.svelte`, `src/lib/i18n.ts` | already committed; touched only to fix a demonstrated bug | ### Files deliberately NOT touched - **PAdES internals** (`src/lib/pades.ts`, `src/lib/pades.test.ts`) — owned by other issues, and the issue's ownership clause says so explicitly. - `src/lib/cms.ts` (the CAdES builder), `src/lib/keystore.ts`'s crypto, `src/lib/x509.ts` parsing: the `expired` / `notYetValid` flags already exist on `SignerCert` (`src/lib/sign.ts`), which is what task 1 asks for. Re-adding them would be a second convention. - `work/`, `original/`, `decompiled*/` — gitignored inputs; the container and `.p12pass` are read at runtime, never printed, never committed. - `docs/` beyond the README rows already updated. ## Ordered tasks 1. **Reproduce and attribute the red gate.** `pnpm test` (full output, failures by file) → compare each failing test against `git show 163c5d69 --stat` to decide pre-existing vs. caused-by-#40. Verify: the failure list with a cause per failure recorded in the report. 2. **Fix the #40-caused failures only**, at the cause (never by weakening a test). Verify: `pnpm exec vitest run <file>` for each file touched, green. 3. **Align the `xmlsec1Verify` hunk with `issue/45`** so the shared file cannot conflict at integration. Verify: `git diff issue/45-… issue/40-… -- src/test/fixtures.ts` shows no hunk touching `xmlsec1Verify`, and `pnpm exec vitest run src/lib/xades.test.ts` stays green. 4. **Full gates.** `pnpm test` → green; `pnpm build` → clean; `git diff --check` → clean. 5. **Smoke.** `bash scripts/smoke-real.sh` with the default `work/certs/old-cert.p12` and the PIN from `.p12pass`; must exit 0 with `WARNING: … expired …` and the openssl re-verification in the output, and the report must assert `valid-but-expired`. Verify: `echo $?` = 0. 6. **Report.** `.bullet/meta/issue-40.report.md` with the outcome, commit hashes, one line per gate. ## Open questions (assumption stated, moving on) - *Are the 7 failures pre-existing on `main` or caused by #40?* Assumed mixed until task 1 shows it. Hard-law forbids checking out `main` in this worktree, so attribution is done by reading the failing assertions against the diff, not by a baseline run. - *Is committing the `xmlsec1Verify` regex part of #40?* #45 owns that change and already committed it. Assumption: the earlier session needed it because this box runs `xmlsec1 1.3.12` (which prints `Verification status: OK`, not `status: OK`) and the suite is otherwise red. Keep it, but align it with #45's exact text so the two branches do not conflict. - *Does anything else construct a `VerificationReport`?* Assumption: only `verify/cms.ts`, `verify/xades.ts` and the error paths in `verify/index.ts`; `status` was added to all of them. A missed producer would be a `pnpm build` type error, which task 4 catches. ## Risk and boring fallback - **Risk: the failures are unrelated flakiness (jsdom/testing-library dialog timing).** Fallback: re-run the single file in isolation; if it passes alone and fails only in the full run, report it as a pre-existing suite-level flake with the evidence and leave it untouched. - **Risk: `openssl req -not_before/-not_after` needs OpenSSL ≥ 3.4.** This box has 4.0.3, so the fixture works here; a contributor on 3.0 would see a fixture error. Fallback: that is already documented in the fixture's comment; no code change. - **Risk: fixing the fixture-hunk alignment could break the XAdES tests.** Fallback: revert to the current hunk (the reconciler resolves the one-line conflict) and note it in the report. - **Budget risk.** If task 2 exceeds ~15 minutes: stop, commit what is verified, and report PARTIAL with the exact failing command and its first error line.
Author
Owner

DONE — branch issue/40-expired-cert-signing-works-wit.

Commits: 989f6978 (verify verdict), ec631ada (amber UI), 13dc5217 (fixtures+tests), f0e785bf (real-cert smoke + scripts/smoke-real.sh), 163c5d69 (docs), 05799d83 (xmlsec1 hunk aligned with #45), 0b87fc36 (App: banner + signing not blocked), 64d4be2b (VerifyReport banner test).

Gates:

  • pnpm test — exit 0, 18 files / 150 tests. Red on arrival for load reasons only: while the rest of the fleet ran its suites (load 12.5 on 4 CPUs) 7–9 tests across 4 untouched files tripped their 1s waitFor timeouts, failing set different every run; CertPicker.test.ts passes 3/3 alone, and at load ~9.5 the plain suite ran green twice (also --maxWorkers=2: 150/150).
  • pnpm build — exit 0.
  • bash scripts/smoke-real.sh — exit 0: WARNING: … expired 2026-03-29T06:34:25.000Z — signing anyway, openssl: CMS Verification successful, our verifier reports valid-but-expired.
  • git diff --check — exit 0.
  • Headless Chromium on pnpm dev: amber role=alert banner with the expiry date, Firmar enabled.

Full detail in .bullet/meta/issue-40.report.md; decisions for a human are vitest worker cap, the shared xmlsec1Verify hunk with #45, the picker date locale, and the smoke test

DONE — branch `issue/40-expired-cert-signing-works-wit`. Commits: `989f6978` (verify verdict), `ec631ada` (amber UI), `13dc5217` (fixtures+tests), `f0e785bf` (real-cert smoke + scripts/smoke-real.sh), `163c5d69` (docs), `05799d83` (xmlsec1 hunk aligned with #45), `0b87fc36` (App: banner + signing not blocked), `64d4be2b` (VerifyReport banner test). Gates: - `pnpm test` — exit 0, 18 files / 150 tests. Red on arrival for load reasons only: while the rest of the fleet ran its suites (load 12.5 on 4 CPUs) 7–9 tests across 4 untouched files tripped their 1s `waitFor` timeouts, failing set different every run; `CertPicker.test.ts` passes 3/3 alone, and at load ~9.5 the plain suite ran green twice (also `--maxWorkers=2`: 150/150). - `pnpm build` — exit 0. - `bash scripts/smoke-real.sh` — exit 0: `WARNING: … expired 2026-03-29T06:34:25.000Z — signing anyway`, `openssl: CMS Verification successful`, our verifier reports `valid-but-expired`. - `git diff --check` — exit 0. - Headless Chromium on `pnpm dev`: amber `role=alert` banner with the expiry date, `Firmar` enabled. Full detail in `.bullet/meta/issue-40.report.md`; decisions for a human are vitest worker cap, the shared `xmlsec1Verify` hunk with #45, the picker date locale, and the smoke test
Author
Owner

bullet: reviewer launched (model 9router/reviewer, independent of coder).

bullet: reviewer launched (model `9router/reviewer`, independent of coder).
Author
Owner

REVIEW: CLEAN — commit 64d4be2b: findings: none; UNFIXED: none

REVIEW: CLEAN — commit 64d4be2b: findings: none; UNFIXED: none
Author
Owner

bullet: review CLEAN — ready to publish.

bullet: review CLEAN — ready to publish.
Author
Owner

bullet: branch issue/40-expired-cert-signing-works-wit not on origin — cannot integrate.

bullet: branch `issue/40-expired-cert-signing-works-wit` not on origin — cannot integrate.
Author
Owner

bullet: PR #52 open → bullet-develop (auto-merge follows).

bullet: PR #52 open → `bullet-develop` (auto-merge follows).
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

Claimed — branch issue/40-expired-cert-signing-works-wit. Doing: re-applying #40 (expired-cert signing warning + valid-but-expired verify state) on top of bullet-develop and reconciling the 3 conflicted files (README.md, scripts/smoke-real.sh, src/test/fixtures.ts).

Claimed — branch `issue/40-expired-cert-signing-works-wit`. Doing: re-applying #40 (expired-cert signing warning + valid-but-expired verify state) on top of bullet-develop and reconciling the 3 conflicted files (README.md, scripts/smoke-real.sh, src/test/fixtures.ts).
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: worktree gone and unrecoverable — cannot publish.

bullet: worktree gone and unrecoverable — cannot publish.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

Claimed — branch issue/40-expired-cert-signing-works-wit. Doing: re-applying #40 (expired-cert warning + valid-but-expired verify) onto bullet-develop and reconciling conflicts.

Claimed — branch `issue/40-expired-cert-signing-works-wit`. Doing: re-applying #40 (expired-cert warning + valid-but-expired verify) onto bullet-develop and reconciling conflicts.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

Claimed — branch issue/40-expired-cert-signing-works-wit. Doing: re-applying expired-cert warning work onto bullet-develop and resolving conflicts.

Claimed — branch `issue/40-expired-cert-signing-works-wit`. Doing: re-applying expired-cert warning work onto bullet-develop and resolving conflicts.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

Claimed — branch issue/40-expired-cert-signing-works-wit. Doing: re-applying expired-cert signing onto bullet-develop and resolving conflicts.

Claimed — branch `issue/40-expired-cert-signing-works-wit`. Doing: re-applying expired-cert signing onto bullet-develop and resolving conflicts.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

RECONCILED: trunk work merged into bullet-develop (conflicts resolved: none — origin/main abda84d9 already an ancestor via merge 58bdf0f7; PR #48 mergeable=true)

RECONCILED: trunk work merged into bullet-develop (conflicts resolved: none — origin/main abda84d9 already an ancestor via merge 58bdf0f7; PR #48 mergeable=true)
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

Claimed — branch issue/40-expired-cert-signing-works-wit. Doing: re-applying expired-cert signing + verify warning onto bullet-develop, resolving README/smoke-real/fixtures conflicts.

Claimed — branch `issue/40-expired-cert-signing-works-wit`. Doing: re-applying expired-cert signing + verify warning onto bullet-develop, resolving README/smoke-real/fixtures conflicts.
Author
Owner

Claimed — branch bullet-develop. Doing: finish the interrupted issue/40 merge, resolve README.md, scripts/smoke-real.sh, src/test/fixtures.ts conflicts.

Claimed — branch `bullet-develop`. Doing: finish the interrupted issue/40 merge, resolve README.md, scripts/smoke-real.sh, src/test/fixtures.ts conflicts.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

Claimed — branch issue/40-expired-cert-signing-works-wit. Doing: re-applying expired-cert signing warning + verify valid-but-expired state on top of bullet-develop, resolving conflicts.

Claimed — branch `issue/40-expired-cert-signing-works-wit`. Doing: re-applying expired-cert signing warning + verify valid-but-expired state on top of bullet-develop, resolving conflicts.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

Claimed — branch bullet-develop. Doing: reconcile trunk + integrate issue #40 (3 conflicting files) into bullet-develop.

Claimed — branch `bullet-develop`. Doing: reconcile trunk + integrate issue #40 (3 conflicting files) into bullet-develop.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

Claimed — branch issue/40-expired-cert-signing-works-wit. Doing: re-apply expired-cert warning work onto bullet-develop, resolve conflicts with #45/#44 changes, keep gates green.

Claimed — branch `issue/40-expired-cert-signing-works-wit`. Doing: re-apply expired-cert warning work onto bullet-develop, resolve conflicts with #45/#44 changes, keep gates green.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merge conflicts with bullet-develop — conflict-solver agent owns the worktree until it pushes.

bullet: merge conflicts with `bullet-develop` — conflict-solver agent owns the worktree until it pushes.
Author
Owner

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into bullet-develop; PR auto-merges next tick.

bullet: merge blocked (HTTP 405) — conciliation agent merges trunk work into `bullet-develop`; PR auto-merges next tick.
Author
Owner

bullet: merged into bullet-develop — integration gates green.

bullet: merged into `bullet-develop` — integration gates green.
Author
Owner

bullet: PR #52 closed — work already merged into bullet-develop.

bullet: PR #52 closed — work already merged into `bullet-develop`.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
EduarD3V/AutoFirme#40
No description provided.