Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
1d01c65
refactor(settings): add SettingsOwner with owner recovery core (refs …
mblua Oct 16, 2026
098e641
style(settings): apply rustfmt to P41 owner code (refs #2994)
mblua Oct 16, 2026
a49c420
test(settings): seed P41 owner fixtures with a complete base (refs #2…
mblua Oct 16, 2026
7edfda7
fix(settings): classify panics outside the P41 operation builder (ref…
mblua Oct 16, 2026
3aff790
test(settings): P41 R2 Linux owned directory-symlink alias for lifecy…
mblua Oct 17, 2026
93b4ed2
Merge remote-tracking branch 'origin/main' into refactor/2994-setting…
mblua Oct 17, 2026
c184cc4
test(settings): split P41 publisher_recovery into helpers under the c…
mblua Oct 17, 2026
6983688
test(settings): P41 helper returns Arc<SettingsOwner> from open_active
mblua Oct 17, 2026
9cbd4f2
fix(settings): P41 owner lease rejects .. after a tolerated link; zer…
mblua Oct 17, 2026
1d7f22f
Merge commit '008881557ccd5c5e10a51d4ac60b92c23041d329' into refactor…
mblua Oct 17, 2026
a267299
Merge main into P41 preserving profile identity and Matrix copy changes
mblua Oct 17, 2026
0962012
fix(ci): align screenshot guards with shared test inventory
mblua Oct 17, 2026
a77f8a8
test(sidebar): isolate stale menu response reclamp callback
mblua Oct 17, 2026
6f49534
Merge release main into P41 and adopt upstream screenshot guards
mblua Oct 17, 2026
71532cd
Merge reviewed container UI and message archive main into P41
mblua Oct 17, 2026
b60fb1b
Merge reviewed entity-source main into P41 owner recovery
mblua Oct 18, 2026
f7e525a
Merge reviewed profile-type main into P41 owner recovery
mblua Oct 18, 2026
b1ecc0e
Merge reviewed rail diagnostic main into P41 owner recovery
mblua Oct 18, 2026
60373f6
Merge reviewed blocking-menu resource main into P41 owner recovery
mblua Oct 18, 2026
7263509
Merge reviewed sidebar diagnostics main into P41 owner recovery
mblua Oct 18, 2026
ea10a81
Merge reviewed inert id hash debug main into P41 owner recovery
mblua Oct 18, 2026
b059e2b
Merge current main b127 into P41 owner recovery
mblua Oct 18, 2026
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
46 changes: 46 additions & 0 deletions .github/workflows/pr-regression-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1807,6 +1807,29 @@ jobs:
exit 1
}

# #2994 (E2992): the settings-owner tests in the lib crate. Windows already
# runs them through --lib --bins --tests; this leg lists the filter, refuses
# an empty list, then runs exactly that list serially.
- name: "cargo test (E2992 settings owner, focused)"
working-directory: src-tauri
shell: bash
timeout-minutes: 20
run: |
set -euo pipefail
FILTER=e2992_
cargo test --locked --lib "$FILTER" -- --list 2>&1 | tee test-e2992-list.log
COUNT="$(grep -cE ': test$' test-e2992-list.log || true)"
if [ "$COUNT" -eq 0 ]; then
echo "::error::the ${FILTER} filter lists no tests."
exit 1
fi
echo "listed ${COUNT} ${FILTER} tests"
cargo test --locked --lib "$FILTER" -- --test-threads=1 2>&1 | tee test-e2992.log
grep -qE "^test result: ok\. ${COUNT} passed; 0 failed" test-e2992.log || {
echo "::error::expected exactly ${COUNT} passing ${FILTER} tests."
exit 1
}

rust-linux-release-parity:
name: rust-linux-release-parity
# #1842: the Linux PR gate runs ubuntu-latest (24.04) while the Linux
Expand Down Expand Up @@ -2775,6 +2798,29 @@ jobs:
exit 1
}

# #2994 (E2992): the settings-owner tests in the lib crate. Windows already
# runs them through --lib --bins --tests; this leg lists the filter, refuses
# an empty list, then runs exactly that list serially.
- name: "cargo test (E2992 settings owner, focused)"
working-directory: src-tauri
shell: bash
timeout-minutes: 20
run: |
set -euo pipefail
FILTER=e2992_
cargo test --locked --lib "$FILTER" -- --list 2>&1 | tee test-e2992-list.log
COUNT="$(grep -cE ': test$' test-e2992-list.log || true)"
if [ "$COUNT" -eq 0 ]; then
echo "::error::the ${FILTER} filter lists no tests."
exit 1
fi
echo "listed ${COUNT} ${FILTER} tests"
cargo test --locked --lib "$FILTER" -- --test-threads=1 2>&1 | tee test-e2992.log
grep -qE "^test result: ok\. ${COUNT} passed; 0 failed" test-e2992.log || {
echo "::error::expected exactly ${COUNT} passing ${FILTER} tests."
exit 1
}

rust-fmt:
name: rust-fmt
# Skip branch-deletion push events while still requiring pull request validation.
Expand Down
55 changes: 55 additions & 0 deletions src-tauri/src/config/instance_artifacts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,13 @@ pub(crate) const SETTINGS_LOCK_FILE_NAME: &str = SETTINGS_LOCK_TARGET_NAME;
/// leftover the naming migration deliberately never deletes stays ignored; the
/// one row deliberately not composed by `layered_name!`.
pub(crate) const SETTINGS_RETIRED_LOCK_NAME: &str = "settings.json.lock";
/// #2994 - the settings owner's lifecycle lock: a stable sidecar, separate from
/// the transactional `SETTINGS_LOCK_FILE_NAME`, retained for the owner's whole
/// lifetime and never unlinked on close.
pub(crate) const SETTINGS_OWNER_LOCK_FILE_NAME: &str = "settings.owner.no-git.lock";
/// #2994 - the settings owner's endpoint metadata. Reserved here so the runtime
/// artifact is ignored before any writer publishes it.
pub(crate) const SETTINGS_OWNER_ENDPOINT_FILE_NAME: &str = "settings-owner.endpoint.no-git.json";
/// Covers every settings migration backup instance. The concrete names are
/// composed by their own migrations, so this glob is registry-owned and no
/// writer imports it.
Expand Down Expand Up @@ -941,6 +948,12 @@ pub(crate) const INSTANCE_ARTIFACTS: &[InstanceArtifact] = &[
disposition: Disposition::Ignore,
comment: "# AgentsCommander: persisted session state",
},
InstanceArtifact {
name: SETTINGS_OWNER_ENDPOINT_FILE_NAME,
kind: ArtifactKind::File,
disposition: Disposition::Ignore,
comment: "# AgentsCommander: settings owner endpoint metadata; machine-local runtime state",
},
InstanceArtifact {
name: SETTINGS_BACKUP_ROTATION_GLOB,
kind: ArtifactKind::Glob,
Expand Down Expand Up @@ -983,6 +996,12 @@ pub(crate) const INSTANCE_ARTIFACTS: &[InstanceArtifact] = &[
disposition: Disposition::Ignore,
comment: "# AgentsCommander: retired pre-migration settings write lock; the naming migration never deletes it, so the leftover stays ignored",
},
InstanceArtifact {
name: SETTINGS_OWNER_LOCK_FILE_NAME,
kind: ArtifactKind::File,
disposition: Disposition::Ignore,
comment: "# AgentsCommander: settings owner lifecycle lock; stable sidecar, never unlinked",
},
InstanceArtifact {
name: TELEGRAM_BRIDGE_LOG_FILE_NAME,
kind: ArtifactKind::File,
Expand Down Expand Up @@ -1604,4 +1623,40 @@ mod tests {
);
assert_eq!(LOOP_STATE_TARGET_NAME, "loop.state.no-git.json");
}

/// #2994 (P41) - the owner's lifecycle sidecar and endpoint metadata are Ignore
/// rows in sorted position, distinct from the transactional lock, and leave
/// every existing row in place.
#[test]
fn e2992_p41_owner_ignore() {
ignore_rows_are_unique_and_byte_sorted_by_name();
assert_eq!(SETTINGS_OWNER_LOCK_FILE_NAME, "settings.owner.no-git.lock");
assert_eq!(
SETTINGS_OWNER_ENDPOINT_FILE_NAME,
"settings-owner.endpoint.no-git.json"
);
assert_ne!(SETTINGS_OWNER_LOCK_FILE_NAME, SETTINGS_LOCK_FILE_NAME);
assert_ne!(SETTINGS_OWNER_LOCK_FILE_NAME, SETTINGS_RETIRED_LOCK_NAME);
for name in [
SETTINGS_OWNER_LOCK_FILE_NAME,
SETTINGS_OWNER_ENDPOINT_FILE_NAME,
] {
let rows: Vec<&InstanceArtifact> = INSTANCE_ARTIFACTS
.iter()
.filter(|row| row.name == name)
.collect();
assert_eq!(rows.len(), 1, "{name} must have exactly one row");
assert_eq!(rows[0].kind, ArtifactKind::File);
assert_eq!(rows[0].disposition, Disposition::Ignore);
}
// Neighbouring rows survive unchanged: the transactional lock and the
// retired lock are still Ignore rows of their own.
for name in [
SETTINGS_LOCK_FILE_NAME,
SETTINGS_RETIRED_LOCK_NAME,
"sessions.json",
] {
assert!(ignore_rows().iter().any(|row| row.name == name), "{name}");
}
}
}
Loading
Loading