app

Local-first trade for farms and co-ops
git clone https://radroots.dev/git/app.git
Log | Files | Refs | README | LICENSE

commit 7fab7ac8cc6251942d6ab1c7dde7cb73a393fee7
parent 9f11bd08d04d0fac4a87277753d800615f4eaf92
Author: triesap <tyson@radroots.org>
Date:   Wed, 12 Aug 2026 20:10:52 +0000

test: qualify secret and lifecycle closure

- require regression markers for all six closure findings
- lock secret custody and removal lease source contracts
- reject raw import drafts and global overlay busy gates
- cover fail-closed qualification policy behavior

Diffstat:
Mtools/xtask/src/lib.rs | 128++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 127 insertions(+), 1 deletion(-)

diff --git a/tools/xtask/src/lib.rs b/tools/xtask/src/lib.rs @@ -412,7 +412,27 @@ fn product_shell_audit(root: &Path, inventory: &Inventory, findings: &mut Vec<St ), ( "app/shared/src/commonTest/kotlin/org/harvestcircle/application/ShellOverlaysTest.kt", - &["hcSc012"], + &["hcSc012", "hcSl001", "hcSl006"], + ), + ( + "app/shared/src/commonTest/kotlin/org/harvestcircle/application/ReferenceInputPolicyTest.kt", + &["hcSl001"], + ), + ( + "app/shared/src/commonTest/kotlin/org/harvestcircle/application/HarvestCirclePresenterTest.kt", + &["hcSl002", "hcSl003", "hcSl004", "hcSl005"], + ), + ( + "app/shared/src/commonTest/kotlin/org/harvestcircle/application/HarvestCircleShellPresenterTest.kt", + &["hcSl001", "hcSl006"], + ), + ( + "app/shared/src/commonTest/kotlin/org/harvestcircle/application/ImportSecretDraftTest.kt", + &["hcSl005"], + ), + ( + "app/shared/src/desktopTest/kotlin/org/harvestcircle/ui/shell/FoundationOverlayHostTest.kt", + &["hcSl006"], ), ]; for (path, markers) in regression_matrix { @@ -425,6 +445,52 @@ fn product_shell_audit(root: &Path, inventory: &Inventory, findings: &mut Vec<St } } } + let closure_source_contract: &[(&str, &[&str])] = &[ + ( + "app/shared/src/commonMain/kotlin/org/harvestcircle/application/ReferenceInputPolicy.kt", + &["data object AmbiguousHex", "hasAmbiguousHexShape"], + ), + ( + "app/shared/src/commonMain/kotlin/org/harvestcircle/application/ImportSecretDraft.kt", + &[ + "class ImportSecretDraft private constructor", + "private var characters: CharArray?", + ], + ), + ( + "app/shared/src/commonMain/kotlin/org/harvestcircle/application/PresentationModels.kt", + &[ + "val importDraft: ImportSecretDraft", + "class EditImportDraft private constructor", + ], + ), + ( + "app/shared/src/commonMain/kotlin/org/harvestcircle/application/HarvestCirclePresenter.kt", + &[ + "PendingRemovalLease", + "releaseRemovalRequest", + "ImportSecretDraft", + ], + ), + ( + "app/shared/src/commonMain/kotlin/org/harvestcircle/application/ShellOverlays.kt", + &["ReferenceInputAdmission.AmbiguousHex"], + ), + ( + "app/shared/src/commonMain/kotlin/org/harvestcircle/ui/shell/FoundationOverlayHost.kt", + &["val overlayBusy = (overlay as? FoundationOverlay.ConfirmAction)?.busy == true"], + ), + ]; + for (path, markers) in closure_source_contract { + let source = read_text(root, path); + for marker in *markers { + if !source.contains(marker) { + findings.push(format!( + "{path}: required secret-lifecycle closure source marker is missing: {marker}" + )); + } + } + } let locked_copy = [ ( "app/shared/src/commonMain/kotlin/org/harvestcircle/ui/shell/HarvestCircleShell.kt", @@ -506,11 +572,36 @@ fn product_shell_audit(root: &Path, inventory: &Inventory, findings: &mut Vec<St "selected=true,enabled=false", "selected-as-disabled source shape", ), + ( + "valimportDraft:String", + "raw String import-draft custody source shape", + ), + ( + "dataclassEditImportDraft", + "copyable import-draft intent source shape", + ), ] { if compact.contains(shape) { findings.push(format!("{path}: {diagnostic}")); } } + if path + == "app/shared/src/commonMain/kotlin/org/harvestcircle/ui/shell/FoundationOverlayHost.kt" + && compact.contains( + "funFoundationOverlayHost(state:OverlayState,status:ShellStatusModel,busy:Boolean", + ) + { + findings.push(format!( + "{path}: global busy state must not enter the overlay host" + )); + } + if path == "app/shared/src/commonMain/kotlin/org/harvestcircle/application/ShellOverlays.kt" + && compact.contains("state.identity.busy") + { + findings.push(format!( + "{path}: unrelated identity busy state must not gate overlay admission" + )); + } if normalized_path.ends_with("/harvestcirclescreen.kt") { findings.push(format!("{path}: superseded product-shell screen path")); } @@ -1158,6 +1249,41 @@ mod tests { } #[test] + fn product_shell_audit_rejects_secret_custody_and_global_overlay_busy_shapes() { + let root = fixture("secret-lifecycle-shapes"); + write( + &root, + "app/shared/src/commonMain/kotlin/org/harvestcircle/application/UnsafeDraft.kt", + "data class EditImportDraft(val value: String)\ndata class State(val importDraft: String)\n", + ); + write( + &root, + "app/shared/src/commonMain/kotlin/org/harvestcircle/application/ShellOverlays.kt", + "fun admit(state: State) = state.identity.busy\n", + ); + write( + &root, + "app/shared/src/commonMain/kotlin/org/harvestcircle/ui/shell/FoundationOverlayHost.kt", + "fun FoundationOverlayHost(state: OverlayState, status: ShellStatusModel, busy: Boolean) = Unit\n", + ); + let inventory = Inventory::load(&root).expect("closure shape inventory"); + let mut findings = Vec::new(); + product_shell_audit(&root, &inventory, &mut findings); + for expected in [ + "raw String import-draft custody source shape", + "copyable import-draft intent source shape", + "unrelated identity busy state must not gate overlay admission", + "global busy state must not enter the overlay host", + ] { + assert!( + findings.iter().any(|finding| finding.contains(expected)), + "missing {expected}: {findings:?}" + ); + } + fs::remove_dir_all(root).expect("remove fixture"); + } + + #[test] fn repository_policy_rejects_nested_documentation_and_workflow_roots() { let root = fixture("nested-docs"); write(&root, "app/docs/notes.md", "fixture\n");