Plan M4b: approvals over Mattermost in 15 tasks
Skeletons for new files only; existing files change by exact edits, so no task overwrites an earlier one's work. Each task's tests were run against a reference built in order from master, with the gate at each step and mutations checked; each skeleton compiles and fails its tests, and every todo!() comment was read beside its signature. The reference is kept off this machine. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,75 @@
|
||||
# M4b task 12: approval posts in the state file
|
||||
|
||||
**Branch:** `m4b` (run `git switch m4b`; `git status --short` must be empty, otherwise stop)
|
||||
**Commit subject:** `gatewayd: state, the posts of open approvals, and the turn of a session`
|
||||
|
||||
## Goal
|
||||
|
||||
Two things the serve loop needs from `state.json` (M4b spec, sections 6 and 8):
|
||||
|
||||
- **Approval posts.** The posts of each approval shown and not yet ended, so that at the next
|
||||
start the ones left behind can be marked dead. The field is **optional**: an M4a state file
|
||||
loads unchanged. Like every other field, its ids must be valid, or the file is refused.
|
||||
- **The turn of a session**: where an approval of that session goes (its thread).
|
||||
|
||||
## Files
|
||||
|
||||
- Copy: `crates/gatewayd/tests/state_approvals.rs`
|
||||
- Modify: `crates/gatewayd/src/state.rs`, `docs/implementer-log.md`
|
||||
|
||||
## The changes, exactly
|
||||
|
||||
In `crates/gatewayd/src/state.rs`:
|
||||
|
||||
**1.** In `struct StateFile`, after `in_flight: Vec<InFlight>,`:
|
||||
|
||||
```rust
|
||||
/// Optional, so an M4a state file loads unchanged.
|
||||
#[serde(default)]
|
||||
approvals: Vec<ApprovalPosts>,
|
||||
```
|
||||
|
||||
and after `struct StateFile`:
|
||||
|
||||
```rust
|
||||
/// The posts of an approval shown in Mattermost and not yet ended (M4b spec, section 8).
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
#[serde(deny_unknown_fields)]
|
||||
pub struct ApprovalPosts {
|
||||
pub approval: u64,
|
||||
pub channel: String,
|
||||
/// First part first; the last is the one that is edited when it ends.
|
||||
pub posts: Vec<String>,
|
||||
}
|
||||
```
|
||||
|
||||
**2.** In `StateFile::problem`, after the `in_flight` loop and before `None`: each entry of
|
||||
`approvals` must have a `valid_id` channel and at least one post, all `valid_id`; otherwise
|
||||
`Some(format!("approval {}'s posts are not valid", shown.approval))`.
|
||||
|
||||
**3.** Four methods at the end of `impl State`, each saving (`self.save()`) when it changes
|
||||
something, like the methods already there:
|
||||
|
||||
- `pub fn turn_of(&self, session: &str) -> Option<InFlight>`: the entry of `in_flight` with that
|
||||
session, cloned.
|
||||
- `pub fn add_approval(&mut self, shown: ApprovalPosts) -> Result<(), StateError>`: remove any
|
||||
entry with the same `approval`, push this one, save.
|
||||
- `pub fn remove_approval(&mut self, approval: u64) -> Result<(), StateError>`: remove the entries
|
||||
with that `approval`; save only if one was removed.
|
||||
- `pub fn take_approvals(&mut self) -> Result<Vec<ApprovalPosts>, StateError>`: take them all out
|
||||
(`std::mem::take`); save only when there were some; return them. (As `take_in_flight` does.)
|
||||
|
||||
## Steps
|
||||
|
||||
- [ ] **1. Copy.** `git switch m4b`, then `cp docs/plans/M4b/files/crates/gatewayd/tests/state_approvals.rs crates/gatewayd/tests/`
|
||||
- [ ] **2. See it fail.** `cargo test -p gatewayd --test state_approvals`. Expected: it does not
|
||||
compile.
|
||||
- [ ] **3. Make the three changes.** Run `cargo fmt --all`.
|
||||
- [ ] **4. See it pass.** `cargo test -p gatewayd --test state_approvals --test state --test serve_restart`.
|
||||
Expected: 4, 4 and 7 passed.
|
||||
- [ ] **5. Run the gate.** `make gate`. Expected last line: `gate: ok`.
|
||||
- [ ] **6. Log and commit.** `git add crates/gatewayd docs/implementer-log.md Cargo.lock && git commit`
|
||||
|
||||
## Done when
|
||||
|
||||
- The three suites pass; `make gate` prints `gate: ok`.
|
||||
Reference in New Issue
Block a user