Commit Graph
283 Commits
Author SHA1 Message Date
pj 264a78aca7 docs(ci): say why upload-pages-artifact needs no include-hidden-files
v3 to v5 crossed v4's change to exclude dot-files. build/site has none,
so nothing was dropped, and the underscore directory is not hidden.
2026-08-16 01:23:49 +05:30
pj ae4323a704 ci(replay-ui): name the run directory for what it fuzzes
runs/dogfood and the '### replay-ui dogfood' heading carried the same
naming error as the job name: dogfooding is why the run exists, not what
it fuzzes.
2026-08-16 01:23:02 +05:30
pj baa2229abf ci: pin third-party actions to commit shas
buf-setup-action was already pinned with a comment saying why; the other
five rode mutable major tags, so a tag move is an unreviewed change to
what runs. Each major currently resolves to the release named in the
comment, so this freezes today's behaviour rather than changing it.

actions/* stay on major tags: they are first-party to the runner.
2026-08-16 01:22:58 +05:30
pj e2b53c1706 ci: move the folio jdk step to setup-java v5
The only setup-java left on v4; every other one moved.
2026-08-16 01:22:51 +05:30
pj c70d36d18d ci: reuse the headless-chrome action in the browser job
Same three steps the examples workflow needs, and the comment explaining
the AppArmor sysctl now lives in one place.
2026-08-16 01:22:51 +05:30
pj 52ee0ad424 ci(examples): one dispatch workflow for every example
folio.yml and replay-ui.yml ran the same operation: build sanderling for
a platform, bring a target up, run a spec against it, classify the trace,
upload the run. They are now one matrix over four examples, each naming
its own runner.

The job is named for what it fuzzes. 'dogfood' named why we run it, not
what runs, the same error as a diagnostic that reports a motivation
instead of an observation.

The matrix is computed by a plan job because jobs.<id>.if cannot read the
matrix context, so a static matrix has no way to leave a leg out. Seeds,
budgets, timeouts, runners and artifact names are unchanged.
2026-08-16 01:22:32 +05:30
pj 78ea4dd425 ci(examples): add the replay-ui fixture action
Records a trace and serves it with sanderling replay. The step page URL
is a composite output rather than GITHUB_ENV, so it is scoped to the one
step that drives it.
2026-08-16 01:22:25 +05:30
pj 71442bb85a ci(examples): add the folio setup actions
folio-app holds the per-platform toolchain and app build, so a caller
guards one step instead of eight. folio-simulator boots the simulator,
installs folio and leaves the app stopped.
2026-08-16 01:22:25 +05:30
pj de36939d67 ci: add a headless-chrome composite action
The setup-chrome / apparmor sysctl / launch-check trio is copied across
three jobs. The old comment described setup-chrome v1 semantics: under v2
stable is the default and the alternative is Chrome for Testing latest,
not a dev Chromium, so it is restated for what the pin actually does.
2026-08-16 01:22:20 +05:30
pj 41c6c1e4b9 test(ci): cover the folio classifier's verdicts
21 cases through a stubbed sanderling: every exit path, the drift check,
a missing trace, a zero-byte trace, an empty glob and a truncated line.
Asserts the flags that reached the binary, not just the exit code.

Invoked as bash -eo pipefail -c, which is what a run: block does. Running
folio-run.sh itself under -e would kill it at the first non-zero
sanderling test, which is the exit code it exists to read.
2026-08-16 01:08:45 +05:30
pj cd3bc51a0d fix(ci): fail folio when a gated property is not in the spec
Nothing tied GATED_PROPERTIES to the spec it gates. Renaming a property
left the classifier matching nothing: ios and web blamed the spec for
finding a different bug, and android silently reclassified a real
conviction as 'judging health only' and stayed green.

replay-ui-summary.sh already makes this check for its own list. The spec
path becomes SPEC-overridable the same way, so the check is testable.
2026-08-16 01:08:40 +05:30
pj 6263aa4c6c fix(ci): a run that wrote no trace is not evidence about folio
run_dir is empty when the run produced no output directory, and the
fallback made trace ./trace.jsonl. A stray trace in the working directory
was then read as this run's, so a run that wrote nothing reported 'found
the submit bug' and exited 0, defeating the missing-trace check below it.
2026-08-16 01:08:27 +05:30
pj 7f9c5df7db fix(ci): close shell injection into the npm publish job
A refname is attacker-controlled and git permits backtick, $, (, ; and |
in it. Three sites substituted it into a run: block, and NODE_AUTH_TOKEN
sat at job level, so a pushed tag ran arbitrary commands with the publish
credential in reach.

The tag now goes through env:, is validated against an anchored version
pattern before anything consumes it, and reaches the other jobs as a job
output. The token is scoped to the publish step. release-npm declares
contents: read instead of inheriting the repo default.
2026-08-16 01:00:40 +05:30
pj 5b6816956f docs(ci): the cross-fade wait does not fire on ci, say so 2026-08-16 00:50:06 +05:30
pj 71134a3347 docs(ci): the ios leg convicts on the runner now, and why it did not before 2026-08-16 00:23:56 +05:30
pj d977265b30 Merge branch 'clear-state-must-happen' into correctness-and-spec-skills 2026-08-16 00:22:59 +05:30
pj ea952378fe test(android): name the uninstall failure for what it says, not why 2026-08-16 00:07:58 +05:30
pj 87aa7d9284 docs(android): say why the uninstall text cannot be read 2026-08-16 00:07:12 +05:30
pj 6234bf5ba0 fix(ios): a failed devicectl uninstall must fail the reinstall
same hole as the simulator path: devicectl install over an app keeps its data, and the discarded uninstall error hid it. Uninstalling a bundle id that is not installed exits 0 with 'App uninstalled.' on a paired iPhone, so a failure here is always real.
2026-08-16 00:02:36 +05:30
pj abc5e7db3e fix(ios): a failed simctl uninstall must fail the reinstall
simctl install over an installed app carries its data container across, so discarding the uninstall error reported a clear-state that never happened. Uninstalling an app that is not installed exits 0 on a booted simulator, so every failure here is a real one.
2026-08-16 00:01:40 +05:30
pj 1ec6eb3847 fix(android): a refused uninstall must not pass for clear-state
adb uninstall answers Failure [DELETE_FAILED_INTERNAL_ERROR] both when the package was never installed and when it refuses to remove one, so the failure text cannot say which happened and the old code installed over the top either way, keeping the data clear-state was asked to drop. Ask pm path instead, and fall back to pm clear when the app is still there.
2026-08-16 00:00:36 +05:30
pj 17f0a020fa Merge branch 'spec-authoring-skills' into trial-merge 2026-08-15 23:04:37 +05:30
pj 112d347432 refactor(folio): name the balance property for the bound it asserts
it stopped being an equality and became |delta| <= typed, so the old name
demanded more than the property does. renamed with the ci gate's
GATED_PROPERTIES in the same commit so the gate never sees a name it does
not know.
2026-08-15 23:04:15 +05:30
pj 6a7764eac7 Merge branch 'folio-spec-attribution' into trial-merge 2026-08-15 23:03:50 +05:30
pj 8ad68b278f docs(folio): record why a banked card reading can be trusted as current
The freshness rule rests on the app popping one entry back to the ledger,
not on anything the frame carries, so the assumption and the measurements
behind it belong next to it.
2026-08-15 23:02:42 +05:30
pj 4027aa1e44 test(folio): pin that a commit stays in the window until Home reads it
The interaction that keeps a stale Home card list from ever banking counts
the budget has already forgotten: a submit lands on the ledger, so the
reading that resets the window is a whole action later and the submit is
still in it. Characterization, not a regression: no code changed and it
cannot go red first.
2026-08-15 23:02:37 +05:30
pj b554a9ecee docs(manual): correct the flags the cli reference gets wrong
--launcher-activity does not exist in cmd/sanderling/main.go. --device,
--android-app-path and --arm do and were undocumented. runs.md still listed
--max-steps and --exit-on-violation as unshipped, and described --clear-data
as opt-in when the default is already true, contradicting itself ten lines on.
2026-08-15 23:00:16 +05:30
pj b241a2cc64 Merge branch 'trial-merge' into spec-authoring-skills 2026-08-15 22:59:47 +05:30
pj 1adbb35305 Merge branch 'skills-setup-and-triage' into spec-authoring-skills 2026-08-15 22:59:47 +05:30
pj fb1b482ab1 docs(skills): point the setup skill at its siblings 2026-08-15 22:58:41 +05:30
pj ffc857f58f Merge branch 'spec-authoring-skills' into skills-setup-and-triage 2026-08-15 22:58:07 +05:30
pj a51c8cb742 docs(skills): add a run triage skill 2026-08-15 22:57:42 +05:30
pj 221c9a91b5 Merge branch 'spec-authoring-skill-writing' into spec-authoring-skills 2026-08-15 22:57:18 +05:30
pj 64b9087be2 Merge branch 'sanderling-property-patterns-skill' into spec-authoring-skills 2026-08-15 22:57:18 +05:30
pj ae0694cd8b docs(skills): add a setup skill for adopting sanderling 2026-08-15 22:56:31 +05:30
pj d79fb3f2d6 docs(skills): name the selector keys that still substring match 2026-08-15 22:56:28 +05:30
pj 7068b03ffc docs(skills): ground the property patterns catalogue in the merged specs 2026-08-15 22:55:56 +05:30
pj 2394c29d10 docs(skills): add a spec authoring skill
covers hooks, extractors, selectors, properties, actions and the order to write them in, with a complete sample spec that typechecks against the real export surface.
2026-08-15 22:55:15 +05:30
pj 21a020de74 docs(folio): say what property 2 demands now that it is a bound 2026-08-15 22:55:13 +05:30
pj 6e8e6d51fe fix(folio): bound the total-balance move instead of demanding it exactly
The write finishes before AddTransactionViewModel navigates, but nothing
establishes that Home's total has re-rendered before the frame is read, and
an equality convicts a healthy app for a total one frame behind. A delta of
zero is exactly the shape nine of the eleven measured android false
convictions had. 2x still exceeds x, so all four recorded convictions
survive, checked against the traces.

The trade is real: a balance that moves by LESS than the amount typed is no
longer judged anywhere in this spec.
2026-08-15 22:55:09 +05:30
pj 48e901bd9b Merge branch 'android-home-diagnostic' into trial-merge 2026-08-15 22:51:48 +05:30
pj 404ce4bcbb Merge branch 'spec-authoring-skills' into sanderling-property-patterns-skill 2026-08-15 22:50:56 +05:30
pj ac4846bf55 Merge branch 'trial-merge' into spec-authoring-skills 2026-08-15 22:50:21 +05:30
pj 1ca812beed docs(skills): add a property patterns catalogue skill 2026-08-15 22:48:27 +05:30
pj e61b39f2e3 test(testrun): cover the sidecar shutdown path after an early exit 2026-08-15 22:46:47 +05:30
pj 708a8a2929 fix(testrun): report a sidecar that dies at startup as the exit it was 2026-08-15 22:42:26 +05:30
pj 049b8d513e docs(skills): add a spec review skill and the skills index 2026-08-15 22:39:47 +05:30
pj f819dad7b6 fix(testrun): preflight resolves adb through the sdk, not just PATH 2026-08-15 22:39:38 +05:30
pj 3af6791029 docs(cli): the android doctor checks are not path-only 2026-08-15 22:38:34 +05:30
pj 22115a6c25 fix(doctor): resolve adb and emulator the way a run does 2026-08-15 22:38:23 +05:30