feat: add offline casting flow and local history sessions

Replace the development fixture shell with method intro, question, coin entry, and result screens. Persist locked casts in private Room storage under the save policy, and document remaining P2 content and P4 history-list gaps.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
QiuSW
2026-08-19 10:58:09 +08:00
co-authored by Cursor
parent d82ab836a2
commit 4235cf9011
47 changed files with 3075 additions and 355 deletions
+61
View File
@@ -0,0 +1,61 @@
import { readFile } from "node:fs/promises";
import path from "node:path";
import { repositoryRoot } from "./repository-files.mjs";
const manifestPath = path.join(repositoryRoot, "app", "src", "main", "AndroidManifest.xml");
const backupRulesPath = path.join(
repositoryRoot,
"app",
"src",
"main",
"res",
"xml",
"backup_rules.xml",
);
const extractionRulesPath = path.join(
repositoryRoot,
"app",
"src",
"main",
"res",
"xml",
"data_extraction_rules.xml",
);
const [manifest, backupRules, extractionRules] = await Promise.all([
readFile(manifestPath, "utf8"),
readFile(backupRulesPath, "utf8"),
readFile(extractionRulesPath, "utf8"),
]);
const failures = [];
if (!manifest.includes('android:allowBackup="false"')) {
failures.push("Android backup must remain disabled");
}
if (!manifest.includes('android:usesCleartextTraffic="false"')) {
failures.push("cleartext traffic must remain disabled");
}
if (/android\.permission\.INTERNET/u.test(manifest)) {
failures.push("the offline application must not request INTERNET permission");
}
for (const domain of ["root", "file", "database", "sharedpref", "external"]) {
const exclusion = `<exclude domain="${domain}" path="." />`;
if (!backupRules.includes(exclusion)) {
failures.push(`legacy backup rules do not exclude ${domain}`);
}
const extractionOccurrences = extractionRules.split(exclusion).length - 1;
if (extractionOccurrences !== 2) {
failures.push(
`data extraction rules must exclude ${domain} from cloud backup and device transfer`,
);
}
}
if (failures.length > 0) {
console.error("Local-data boundary verification failed:");
for (const failure of failures) console.error(`- ${failure}`);
process.exitCode = 1;
} else {
console.log("Local-data boundary verification passed.");
}