From 6abcbb7da52a06136aaff6f37487ab7a83e7caa7 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:08:03 -0400 Subject: [PATCH 01/20] Add live Android sensor-list probe --- experiments/android-sensors/sensors.c | 35 +++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 experiments/android-sensors/sensors.c diff --git a/experiments/android-sensors/sensors.c b/experiments/android-sensors/sensors.c new file mode 100644 index 0000000..1076a89 --- /dev/null +++ b/experiments/android-sensors/sensors.c @@ -0,0 +1,35 @@ +#include + +#include + +int main(void) { + ASensorManager *manager = ASensorManager_getInstance(); + if (manager == NULL) { + fputs("sensors: Android sensor manager is unavailable\n", stderr); + return 1; + } + + ASensorList sensors = NULL; + int count = ASensorManager_getSensorList(manager, &sensors); + if (count < 0) { + fputs("sensors: Android sensor list failed\n", stderr); + return 1; + } + + puts("type\tname\tvendor\tresolution\tmin_delay_us"); + + for (int i = 0; i < count; ++i) { + const ASensor *sensor = sensors[i]; + const char *name = ASensor_getName(sensor); + const char *vendor = ASensor_getVendor(sensor); + + printf("%d\t%s\t%s\t%.9g\t%d\n", + ASensor_getType(sensor), + name == NULL ? "" : name, + vendor == NULL ? "" : vendor, + ASensor_getResolution(sensor), + ASensor_getMinDelay(sensor)); + } + + return 0; +} From 0db76bf84e4feba83dbe2eb68a3daf94e6ad99a0 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:08:13 -0400 Subject: [PATCH 02/20] Document live Android sensor acceptance boundary --- experiments/android-sensors/README.md | 55 +++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 experiments/android-sensors/README.md diff --git a/experiments/android-sensors/README.md b/experiments/android-sensors/README.md new file mode 100644 index 0000000..250131f --- /dev/null +++ b/experiments/android-sensors/README.md @@ -0,0 +1,55 @@ +# Live Android sensors + +This is the first live Android probe for the proposed Grease hardware namespace. +It deliberately tests the public native Android sensor boundary before adding a +synthetic filesystem, 9P, FUSE, IIO, direct HAL access, or a Termux:API bridge. + +The first program is only `sensors`: enumerate the sensors visible through +`libandroid` and print stable tab-separated metadata. This source is an Android +experiment, not a Grease execution receipt. + +## Build and run on Android + +From this directory in Termux: + +```sh +cc -std=c11 -O2 -Wall -Wextra sensors.c -landroid -o sensors +./sensors +``` + +The expected shape is: + +```text +type name vendor resolution min_delay_us +1 ... ... ... ... +``` + +The exact sensor names and metadata are device data and must not be baked into +tests. + +## Acceptance boundary + +The direct path is accepted only after the exact source revision: + +1. compiles in the actual Android/Termux environment; +2. launches on the physical device; and +3. returns the device's sensor list through `libandroid`. + +A successful Termux:API command, emulator run, host cross-build, or source +inspection does not substitute for that physical-device result. + +## Next steps after enumeration works + +Add, in order: + +1. one fresh accelerometer sample using the native Android event queue; +2. a continuous accelerometer event stream; +3. the semantic hardware objects that can later be presented as + `/hardware/sensors`, `/hardware/sensors/accelerometer/info`, + `/hardware/sensors/accelerometer/sample`, and + `/hardware/sensors/accelerometer/events`; +4. alternative adapters such as Termux:API, Linux IIO, 9P, or FUSE without + changing those object meanings. + +The Android mechanism is an adapter. It must not define the permanent Grease +hardware semantics merely because it is the first implementation. From ef9bd333f18a0902ebe827e47025561d265014e6 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:15:20 -0400 Subject: [PATCH 03/20] Make Android sensor probe cloud-buildable --- experiments/android-sensors/sensors.c | 92 ++++++++++++++++++++------- 1 file changed, 68 insertions(+), 24 deletions(-) diff --git a/experiments/android-sensors/sensors.c b/experiments/android-sensors/sensors.c index 1076a89..557e27f 100644 --- a/experiments/android-sensors/sensors.c +++ b/experiments/android-sensors/sensors.c @@ -1,35 +1,79 @@ -#include +typedef struct ASensorManager ASensorManager; +typedef struct ASensor ASensor; +typedef const ASensor *const *ASensorList; -#include +extern ASensorManager *ASensorManager_getInstance(void); +extern int ASensorManager_getSensorList(ASensorManager *, ASensorList *); +extern const char *ASensor_getName(const ASensor *); +extern const char *ASensor_getVendor(const ASensor *); +extern int ASensor_getType(const ASensor *); +extern int ASensor_getMinDelay(const ASensor *); -int main(void) { - ASensorManager *manager = ASensorManager_getInstance(); - if (manager == NULL) { - fputs("sensors: Android sensor manager is unavailable\n", stderr); - return 1; +static long write_bytes(int fd, const char *data, unsigned int count) { + register long r0 __asm__("r0") = fd; + register long r1 __asm__("r1") = (long)data; + register long r2 __asm__("r2") = count; + register long r7 __asm__("r7") = 4; + __asm__ volatile("svc 0" : "+r"(r0) : "r"(r1), "r"(r2), "r"(r7) : "memory"); + return r0; +} + +__attribute__((noreturn)) static void exit_process(int status) { + register long r0 __asm__("r0") = status; + register long r7 __asm__("r7") = 1; + __asm__ volatile("svc 0" : : "r"(r0), "r"(r7) : "memory"); + for (;;) { } +} + +static unsigned int text_length(const char *text) { + unsigned int n = 0; + if (!text) return 0; + while (text[n]) ++n; + return n; +} + +static void write_text(const char *text) { + if (text) write_bytes(1, text, text_length(text)); +} + +static void write_hex(unsigned int value) { + char out[10]; + static const char digits[] = "0123456789abcdef"; + out[0] = '0'; out[1] = 'x'; + for (unsigned int i = 0; i < 8; ++i) { + unsigned int shift = 28 - i * 4; + out[2 + i] = digits[(value >> shift) & 15u]; } + write_bytes(1, out, 10); +} - ASensorList sensors = NULL; - int count = ASensorManager_getSensorList(manager, &sensors); - if (count < 0) { - fputs("sensors: Android sensor list failed\n", stderr); - return 1; +static int run(void) { + ASensorManager *manager = ASensorManager_getInstance(); + if (!manager) { + write_text("sensor manager unavailable\n"); + return 2; } - puts("type\tname\tvendor\tresolution\tmin_delay_us"); + ASensorList list = 0; + int count = ASensorManager_getSensorList(manager, &list); + if (count < 0 || !list) { + write_text("sensor list unavailable\n"); + return 3; + } + write_text("count\t"); write_hex((unsigned int)count); write_text("\n"); + write_text("index\ttype\tmin_delay_us\tname\tvendor\n"); for (int i = 0; i < count; ++i) { - const ASensor *sensor = sensors[i]; - const char *name = ASensor_getName(sensor); - const char *vendor = ASensor_getVendor(sensor); - - printf("%d\t%s\t%s\t%.9g\t%d\n", - ASensor_getType(sensor), - name == NULL ? "" : name, - vendor == NULL ? "" : vendor, - ASensor_getResolution(sensor), - ASensor_getMinDelay(sensor)); + const ASensor *sensor = list[i]; + write_hex((unsigned int)i); write_text("\t"); + write_hex((unsigned int)ASensor_getType(sensor)); write_text("\t"); + write_hex((unsigned int)ASensor_getMinDelay(sensor)); write_text("\t"); + write_text(ASensor_getName(sensor)); write_text("\t"); + write_text(ASensor_getVendor(sensor)); write_text("\n"); } - return 0; } + +void _start(void) { + exit_process(run()); +} From 34033634528809ea6e61b786beb4c378fdd9b892 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:15:26 -0400 Subject: [PATCH 04/20] Add link-only libandroid sensor stub --- experiments/android-sensors/link-libandroid-stub.c | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 experiments/android-sensors/link-libandroid-stub.c diff --git a/experiments/android-sensors/link-libandroid-stub.c b/experiments/android-sensors/link-libandroid-stub.c new file mode 100644 index 0000000..ecf5770 --- /dev/null +++ b/experiments/android-sensors/link-libandroid-stub.c @@ -0,0 +1,10 @@ +void *ASensorManager_getInstance(void) { return 0; } +int ASensorManager_getSensorList(void *manager, const void ***list) { + (void)manager; + (void)list; + return 0; +} +const char *ASensor_getName(const void *sensor) { (void)sensor; return 0; } +const char *ASensor_getVendor(const void *sensor) { (void)sensor; return 0; } +int ASensor_getType(const void *sensor) { (void)sensor; return 0; } +int ASensor_getMinDelay(const void *sensor) { (void)sensor; return 0; } From 7be713cb8232ecd05f5f3e1f85a59c1ccc416234 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:15:54 -0400 Subject: [PATCH 05/20] Add cloud-built ARMv7 Android sensor probe --- experiments/android-sensors/sensors.armv7.b64 | 1 + 1 file changed, 1 insertion(+) create mode 100644 experiments/android-sensors/sensors.armv7.b64 diff --git a/experiments/android-sensors/sensors.armv7.b64 b/experiments/android-sensors/sensors.armv7.b64 new file mode 100644 index 0000000..0fac04c --- /dev/null +++ b/experiments/android-sensors/sensors.armv7.b64 @@ -0,0 +1 @@ +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 \ No newline at end of file From 1609c30f2535b6dfc7f607cfdd655398822af03b Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:17:03 -0400 Subject: [PATCH 06/20] Record ARMv7 sensor probe checksum --- experiments/android-sensors/sensors.armv7.sha256 | 1 + 1 file changed, 1 insertion(+) create mode 100644 experiments/android-sensors/sensors.armv7.sha256 diff --git a/experiments/android-sensors/sensors.armv7.sha256 b/experiments/android-sensors/sensors.armv7.sha256 new file mode 100644 index 0000000..2cfc594 --- /dev/null +++ b/experiments/android-sensors/sensors.armv7.sha256 @@ -0,0 +1 @@ +9270b8ebd1243b388a17f24a5cad4883363ca7a5dd122431df2d2a7dc49c87f5 sensors From 20c8bdb6356a36d8dffaf56686e51a194a237bb4 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:18:29 -0400 Subject: [PATCH 07/20] Keep Android compilation off the phone --- experiments/android-sensors/README.md | 82 +++++++++++++++++++++------ 1 file changed, 64 insertions(+), 18 deletions(-) diff --git a/experiments/android-sensors/README.md b/experiments/android-sensors/README.md index 250131f..2d833c0 100644 --- a/experiments/android-sensors/README.md +++ b/experiments/android-sensors/README.md @@ -4,39 +4,85 @@ This is the first live Android probe for the proposed Grease hardware namespace. It deliberately tests the public native Android sensor boundary before adding a synthetic filesystem, 9P, FUSE, IIO, direct HAL access, or a Termux:API bridge. -The first program is only `sensors`: enumerate the sensors visible through -`libandroid` and print stable tab-separated metadata. This source is an Android +The first program is only `sensors`: enumerate the sensors visible through the +phone's `libandroid` and print tab-separated metadata. This is an Android experiment, not a Grease execution receipt. -## Build and run on Android +## Phone workflow -From this directory in Termux: +Do not install a compiler or Android NDK on the phone for this experiment. The +phone is the execution target only: pull the already-built ARMv7 executable, +check it, and run it. + +The repository carries the executable as `sensors.armv7.b64` because GitHub's +text-content path is being used for this small experimental artifact. Decode it +on the phone, mark it executable, verify the recorded SHA-256, and run it. + +The current executable is 3556 bytes and has SHA-256: + +```text +9270b8ebd1243b388a17f24a5cad4883363ca7a5dd122431df2d2a7dc49c87f5 +``` + +It is an ARMv7 Thumb-2 PIE with `/system/bin/linker` as interpreter and one +runtime dependency: the phone's real `libandroid.so`. + +## Cloud build + +`sensors.c` is freestanding so the cross-build does not need Android headers or +libc. It writes output with ARM Linux system calls and calls only the public +Android sensor symbols it needs. + +`link-libandroid-stub.c` is link-time scaffolding only. It gives the host linker +the `libandroid.so` symbol names and SONAME. The stub is not shipped to the +phone; Android's dynamic linker must load the phone's real `libandroid.so`. + +The artifact currently checked in was produced with Clang/LLD 17 using: ```sh -cc -std=c11 -O2 -Wall -Wextra sensors.c -landroid -o sensors -./sensors +clang --target=armv7a-linux-gnueabi -march=armv7-a -mthumb \ + -ffreestanding -fPIC -fno-stack-protector -fno-builtin -nostdlib \ + -fuse-ld=lld -shared -Wl,-soname,libandroid.so -Wl,--no-undefined \ + -o /tmp/libandroid.so link-libandroid-stub.c + +clang --target=armv7a-linux-gnueabi -march=armv7-a -mthumb -Oz \ + -ffreestanding -fPIE -fno-stack-protector -fno-builtin -nostdlib \ + -c -o /tmp/sensors.o sensors.c + +clang --target=armv7a-linux-gnueabi -fuse-ld=lld -nostdlib \ + -Wl,-pie -Wl,--dynamic-linker=/system/bin/linker -Wl,-e,_start \ + -Wl,--hash-style=both -L/tmp /tmp/sensors.o -landroid -o sensors ``` -The expected shape is: +Host inspection established that the result is a 32-bit ARM EABI5 PIE, its +entry point is Thumb, and its only dynamic library dependency is `libandroid.so`. +That is cross-build evidence only, not Android runtime acceptance. + +## Expected output + +The current minimal formatter uses hexadecimal integers to avoid dragging a C +runtime into the probe. Output has this shape: ```text -type name vendor resolution min_delay_us -1 ... ... ... ... +count 0x00000005 +index type min_delay_us name vendor +0x00000000 0x00000001 0x00002710 ... ... ``` -The exact sensor names and metadata are device data and must not be baked into -tests. +The exact count, names, vendor strings, types, and delays are device data and +must not be baked into acceptance tests. ## Acceptance boundary -The direct path is accepted only after the exact source revision: +The direct path is accepted only after the exact cross-built artifact: -1. compiles in the actual Android/Termux environment; -2. launches on the physical device; and -3. returns the device's sensor list through `libandroid`. +1. launches on the physical Android phone; +2. resolves the sensor entry points from the phone's real `libandroid.so`; and +3. returns that phone's sensor list. -A successful Termux:API command, emulator run, host cross-build, or source -inspection does not substitute for that physical-device result. +A host cross-build, source inspection, emulator result, or Termux:API command +does not substitute for that physical-device result. Conversely, the phone does +not need to compile the source merely to supply runtime acceptance. ## Next steps after enumeration works @@ -51,5 +97,5 @@ Add, in order: 4. alternative adapters such as Termux:API, Linux IIO, 9P, or FUSE without changing those object meanings. -The Android mechanism is an adapter. It must not define the permanent Grease +The Android mechanism is an adapter. It must not define the permanent Grease hardware semantics merely because it is the first implementation. From b9d5707274ae8d9d14ad91badfce867deeec9528 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:44:18 -0400 Subject: [PATCH 08/20] Move sensors source into Grease command tree --- commands/sensors/sensors.c | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100644 commands/sensors/sensors.c diff --git a/commands/sensors/sensors.c b/commands/sensors/sensors.c new file mode 100644 index 0000000..557e27f --- /dev/null +++ b/commands/sensors/sensors.c @@ -0,0 +1,79 @@ +typedef struct ASensorManager ASensorManager; +typedef struct ASensor ASensor; +typedef const ASensor *const *ASensorList; + +extern ASensorManager *ASensorManager_getInstance(void); +extern int ASensorManager_getSensorList(ASensorManager *, ASensorList *); +extern const char *ASensor_getName(const ASensor *); +extern const char *ASensor_getVendor(const ASensor *); +extern int ASensor_getType(const ASensor *); +extern int ASensor_getMinDelay(const ASensor *); + +static long write_bytes(int fd, const char *data, unsigned int count) { + register long r0 __asm__("r0") = fd; + register long r1 __asm__("r1") = (long)data; + register long r2 __asm__("r2") = count; + register long r7 __asm__("r7") = 4; + __asm__ volatile("svc 0" : "+r"(r0) : "r"(r1), "r"(r2), "r"(r7) : "memory"); + return r0; +} + +__attribute__((noreturn)) static void exit_process(int status) { + register long r0 __asm__("r0") = status; + register long r7 __asm__("r7") = 1; + __asm__ volatile("svc 0" : : "r"(r0), "r"(r7) : "memory"); + for (;;) { } +} + +static unsigned int text_length(const char *text) { + unsigned int n = 0; + if (!text) return 0; + while (text[n]) ++n; + return n; +} + +static void write_text(const char *text) { + if (text) write_bytes(1, text, text_length(text)); +} + +static void write_hex(unsigned int value) { + char out[10]; + static const char digits[] = "0123456789abcdef"; + out[0] = '0'; out[1] = 'x'; + for (unsigned int i = 0; i < 8; ++i) { + unsigned int shift = 28 - i * 4; + out[2 + i] = digits[(value >> shift) & 15u]; + } + write_bytes(1, out, 10); +} + +static int run(void) { + ASensorManager *manager = ASensorManager_getInstance(); + if (!manager) { + write_text("sensor manager unavailable\n"); + return 2; + } + + ASensorList list = 0; + int count = ASensorManager_getSensorList(manager, &list); + if (count < 0 || !list) { + write_text("sensor list unavailable\n"); + return 3; + } + + write_text("count\t"); write_hex((unsigned int)count); write_text("\n"); + write_text("index\ttype\tmin_delay_us\tname\tvendor\n"); + for (int i = 0; i < count; ++i) { + const ASensor *sensor = list[i]; + write_hex((unsigned int)i); write_text("\t"); + write_hex((unsigned int)ASensor_getType(sensor)); write_text("\t"); + write_hex((unsigned int)ASensor_getMinDelay(sensor)); write_text("\t"); + write_text(ASensor_getName(sensor)); write_text("\t"); + write_text(ASensor_getVendor(sensor)); write_text("\n"); + } + return 0; +} + +void _start(void) { + exit_process(run()); +} From 68bad082247a80addbf9809ad799c9271c5e3a65 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:44:24 -0400 Subject: [PATCH 09/20] Move libandroid link stub with sensors command --- commands/sensors/link-libandroid-stub.c | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 commands/sensors/link-libandroid-stub.c diff --git a/commands/sensors/link-libandroid-stub.c b/commands/sensors/link-libandroid-stub.c new file mode 100644 index 0000000..ecf5770 --- /dev/null +++ b/commands/sensors/link-libandroid-stub.c @@ -0,0 +1,10 @@ +void *ASensorManager_getInstance(void) { return 0; } +int ASensorManager_getSensorList(void *manager, const void ***list) { + (void)manager; + (void)list; + return 0; +} +const char *ASensor_getName(const void *sensor) { (void)sensor; return 0; } +const char *ASensor_getVendor(const void *sensor) { (void)sensor; return 0; } +int ASensor_getType(const void *sensor) { (void)sensor; return 0; } +int ASensor_getMinDelay(const void *sensor) { (void)sensor; return 0; } From b807711a1f2c538dbbb150dbbae76cead6b0e2e3 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:44:28 -0400 Subject: [PATCH 10/20] Move ARMv7 sensor artifact checksum --- commands/sensors/sensors.armv7.sha256 | 1 + 1 file changed, 1 insertion(+) create mode 100644 commands/sensors/sensors.armv7.sha256 diff --git a/commands/sensors/sensors.armv7.sha256 b/commands/sensors/sensors.armv7.sha256 new file mode 100644 index 0000000..2cfc594 --- /dev/null +++ b/commands/sensors/sensors.armv7.sha256 @@ -0,0 +1 @@ +9270b8ebd1243b388a17f24a5cad4883363ca7a5dd122431df2d2a7dc49c87f5 sensors From 7aad7fde14f8f6038936566dbb15cc0111483cf4 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:44:51 -0400 Subject: [PATCH 11/20] Move ARMv7 sensor artifact into command tree --- commands/sensors/sensors.armv7.b64 | 1 + 1 file changed, 1 insertion(+) create mode 100644 commands/sensors/sensors.armv7.b64 diff --git a/commands/sensors/sensors.armv7.b64 b/commands/sensors/sensors.armv7.b64 new file mode 100644 index 0000000..de3798e --- /dev/null +++ b/commands/sensors/sensors.armv7.b64 @@ -0,0 +1 @@ +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 \ No newline at end of file From 62668497f67c8d28d4f357bc4baea89dc4c07ccc Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:45:56 -0400 Subject: [PATCH 12/20] Restore exact verified ARMv7 sensor artifact bytes --- commands/sensors/sensors.armv7.b64 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/commands/sensors/sensors.armv7.b64 b/commands/sensors/sensors.armv7.b64 index de3798e..0fac04c 100644 --- a/commands/sensors/sensors.armv7.b64 +++ b/commands/sensors/sensors.armv7.b64 @@ -1 +1 @@ -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 \ No newline at end of file +f0VMRgEBAQAAAAAAAAAAAAMAKAABAAAAuQMBADQAAADsCgAAAAIABTQAIAAKACgAEwARAAYAAAA0AAAANAAAADQAAABAAQAAQAEAAAQAAAAEAAAAAwAAAHQBAAB0AQAAdAEAABMAAAATAAAABAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAtgMAALYDAAAEAAAAAAABAAEAAAC4AwAAuAMBALgDAQDIAQAAyAEAAAUAAAAAAAEAAQAAAIAFAACABQIAgAUCAHAAAACACgAABgAAAAAAAQABAAAA8AUAAPAFAwDwBQMAJAAAACQAAAAGAAAAAAABAAIAAACABQAAgAUCAIAFAgBwAAAAcAAAAAYAAAAEAAAAUuV0ZIAFAACABQIAgAUCAHAAAACACgAABAAAAAEAAABR5XRkAAAAAAAAAAAAAAAAAAAAAAAAAAAGAAAAAAAAAAEAAHDgAgAA4AIAAOACAAAwAAAAMAAAAAQAAAAEAAAAL3N5c3RlbS9iaW4vbGlua2VyAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAEgAAABwAAAAAAAAAAAAAABIAAAA5AAAAAAAAAAAAAAASAAAASQAAAAAAAAAAAAAAEgAAAF0AAAAAAAAAAAAAABIAAABtAAAAAAAAAAAAAAASAAAAAQAAAAcAAAABAAAAGgAAAAAAAAAAAAAABwAAAAcAAAAEAAAAAAAAAAMAAAAFAAAAAAAAAAAAAAAGAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAgAAAABBU2Vuc29yTWFuYWdlcl9nZXRJbnN0YW5jZQBBU2Vuc29yTWFuYWdlcl9nZXRTZW5zb3JMaXN0AEFTZW5zb3JfZ2V0VHlwZQBBU2Vuc29yX2dldE1pbkRlbGF5AEFTZW5zb3JfZ2V0TmFtZQBBU2Vuc29yX2dldFZlbmRvcgBsaWJhbmRyb2lkLnNvAAAAANgAAQABAAAA2AABAAEAAADYAAEAAQAAAKwBAQABAAAAwAEBAAEAAAD4AQEAAQAAAPwFAwAWAQAAAAYDABYCAAAEBgMAFgMAAAgGAwAWBAAADAYDABYFAAAQBgMAFgYAAGluZGV4CXR5cGUJbWluX2RlbGF5X3VzCW5hbWUJdmVuZG9yCgAJAGNvdW50CQAKAHNlbnNvciBsaXN0IHVuYXZhaWxhYmxlCgAwMTIzNDU2Nzg5YWJjZGVmAHNlbnNvciBtYW5hZ2VyIHVuYXZhaWxhYmxlCgAAAADwBvgA8AD4AScA3/7nAL8t6bxPAPCo6AAoRtAAIQGRAakA8KroACgAkEXUAZgAKELQKEgoTXhEfUSoRwCYAPBj+CZIeESBRqhHJUh4RKhHJEhP8AALeESCRiNIeESARgCYWEUv0AGYUPgrQFhG0EdARqhHIEYA8Ijo0EdARqhHIEYA8Iro0EdARqhHIEYA8IzoqEdARqhHIEYA8I7oqEdIRqhHC/EBC9rnCEh4RADwHfgCIL3ovI8FSHhEAPAW+AMgvei8jwAgvei8jzL//v/6/v7/df/+/7EAAABu//7/OP/+/68AAABN//7/WLEAIUJcATEAKvvRgLVKHgFGASAEJwDfgL1wR961R/YwARwirfgCEA3xAgEKSwIxe0QUHQjQIPoC9AQ6BPAPBBxdAfgBS/TnASAN8QIBCiIEJwDf3r0Av7H+/v8E4C3lAOaP4iDqjuLs8L7l1NTU1NTU1NTU1NTU1NTU1ADGj+Igyozi1PC85dTU1NQAxo/iIMqM4sjwvOXU1NTUAMaP4iDKjOK88Lzl1NTU1ADGj+IgyozisPC85dTU1NQAxo/iIMqM4qTwvOXU1NTUAMaP4iDKjOKY8Lzl1NTU1AEAAAB/AAAA+///bwAAAAgVAAAAAAAAABcAAAAQAwAAAgAAADAAAAADAAAA8AUDABQAAAARAAAABgAAAIgBAAALAAAAEAAAAAUAAABQAgAACgAAAI0AAAD1/v9v+AEAAAQAAAAQAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQEAAAUBAAAFAQAABQEAAAUBAAAFAQAAY2xhbmcgdmVyc2lvbiAxNy4wLjAgKGh0dHBzOi8vZ2l0aHViLmNvbS9zd2lmdGxhbmcvbGx2bS1wcm9qZWN0LmdpdCAxMDk5OWI2ZDAzNGZlMzE4ZjNkNTZjODNiZGRiNjU3MjU5M2E4YmIwKQBMaW5rZXI6IExMRCAxNy4wLjAgKGh0dHBzOi8vZ2l0aHViLmNvbS9zd2lmdGxhbmcvbGx2bS1wcm9qZWN0LmdpdCAxMDk5OWI2ZDAzNGZlMzE4ZjNkNTZjODNiZGRiNjU3MjU5M2E4YmIwKQBBPQAAAGFlYWJpAAEzAAAAQzIuMDkABgoHQQgBCQIKAwwBDgAPARABEQISBBQBFQAXAxgBGQEaAh4EIgEmAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAEAPH/CwAAALgDAQAAAAAAAAAJAA4AAADJAwEA3AAAAAIACQASAAAAwQMBAAYAAAACAAkAHwAAAMEEAQBAAAAAAgAJACkAAAClBAEAHAAAAAIACQA0AAAAhAQBAAAAAAAAAAkANwAAAKQEAQAAAAAAAAAJADoAAAD8BAEAAAAAAAAACQA9AAAAiQMAABEAAAABAAgATgAAAAAFAQAAAAAAAAAKAFEAAAAQBQEAAAAAAAAACgBUAAAAIAUBAAAAAAAAAAoAVwAAACwFAQAAAAAAAAAKAFoAAAAwBQEAAAAAAAAACgBdAAAAPAUBAAAAAAAAAAoAYAAAAEAFAQAAAAAAAAAKAGMAAABMBQEAAAAAAAAACgBmAAAAUAUBAAAAAAAAAAoAaQAAAFwFAQAAAAAAAAAKAGwAAABgBQEAAAAAAAAACgBvAAAAbAUBAAAAAAAAAAoAcgAAAHAFAQAAAAAAAAAKAHUAAAB8BQEAAAAAAAAACgD9AAAAgAUCAAAAAAAAAgsAeAAAALkDAQAIAAAAEgAJAH8AAAAAAAAAAAAAABIAAACaAAAAAAAAAAAAAAASAAAAtwAAAAAAAAAAAAAAEgAAAMcAAAAAAAAAAAAAABIAAADbAAAAAAAAAAAAAAASAAAA6wAAAAAAAAAAAAAAEgAAAAAuaW50ZXJwAC5keW5zeW0ALmdudS5oYXNoAC5oYXNoAC5keW5zdHIALkFSTS5leGlkeAAucmVsLnBsdAAucm9kYXRhAC50ZXh0AC5wbHQALmR5bmFtaWMALnJlbHJvX3BhZGRpbmcALmdvdC5wbHQALmNvbW1lbnQALkFSTS5hdHRyaWJ1dGVzAC5zeW10YWIALnNoc3RydGFiAC5zdHJ0YWIAAHNlbnNvcnMuYwAkdABydW4AZXhpdF9wcm9jZXNzAHdyaXRlX2hleAB3cml0ZV90ZXh0ACRkACR0ACRkAHdyaXRlX2hleC5kaWdpdHMAJGEAJGQAJGEAJGQAJGEAJGQAJGEAJGQAJGEAJGQAJGEAJGQAJGEAJGQAX3N0YXJ0AEFTZW5zb3JNYW5hZ2VyX2dldEluc3RhbmNlAEFTZW5zb3JNYW5hZ2VyX2dldFNlbnNvckxpc3QAQVNlbnNvcl9nZXRUeXBlAEFTZW5zb3JfZ2V0TWluRGVsYXkAQVNlbnNvcl9nZXROYW1lAEFTZW5zb3JfZ2V0VmVuZG9yAF9EWU5BTUlDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAgAAAHQBAAB0AQAAEwAAAAAAAAAAAAAAAQAAAAAAAAAJAAAACwAAAAIAAACIAQAAiAEAAHAAAAAFAAAAAQAAAAQAAAAQAAAAEQAAAPb//28CAAAA+AEAAPgBAAAYAAAAAgAAAAAAAAAEAAAAAAAAABsAAAAFAAAAAgAAABACAAAQAgAAQAAAAAIAAAAAAAAABAAAAAQAAAAhAAAAAwAAAAIAAABQAgAAUAIAAI0AAAAAAAAAAAAAAAEAAAAAAAAAKQAAAAEAAHCCAAAA4AIAAOACAAAwAAAACQAAAAAAAAAEAAAAAAAAADQAAAAJAAAAQgAAABADAAAQAwAAMAAAAAIAAAANAAAABAAAAAgAAAA9AAAAAQAAADIAAABAAwAAQAMAAHYAAAAAAAAAAAAAAAEAAAABAAAARQAAAAEAAAAGAAAAuAMBALgDAABIAQAAAAAAAAAAAAAEAAAAAAAAAEsAAAABAAAABgAAAAAFAQAABQAAgAAAAAAAAAAAAAAAEAAAAAAAAABQAAAABgAAAAMAAACABQIAgAUAAHAAAAAFAAAAAAAAAAQAAAAIAAAAWQAAAAgAAAADAAAA8AUCAPAFAAAQCgAAAAAAAAAAAAABAAAAAAAAAGgAAAABAAAAAwAAAPAFAwDwBQAAJAAAAAAAAAAAAAAABAAAAAAAAABxAAAAAQAAADAAAAAAAAAAFAYAANsAAAAAAAAAAAAAAAEAAAABAAAAegAAAAMAAHAAAAAAAAAAAO8GAAA+AAAAAAAAAAAAAAABAAAAAAAAAIoAAAACAAAAAAAAAAAAAAAwBwAAEAIAABIAAAAaAAAABAAAABAAAACSAAAAAwAAAAAAAAAAAAAAQAkAAKQAAAAAAAAAAAAAAAEAAAAAAAAAnAAAAAMAAAAAAAAAAAAAAOQJAAAGAQAAAAAAAAAAAAABAAAAAAAAAA== \ No newline at end of file From 06f17703484bdbd03d49fa89a00397e350a8bdc5 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:46:18 -0400 Subject: [PATCH 13/20] Promote live sensor probe to Grease command --- commands/sensors/README.md | 72 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 commands/sensors/README.md diff --git a/commands/sensors/README.md b/commands/sensors/README.md new file mode 100644 index 0000000..fdb70e6 --- /dev/null +++ b/commands/sensors/README.md @@ -0,0 +1,72 @@ +# `sensors` + +`sensors` is a Grease hardware command, not an Android experiment. Its job is to enumerate sensing hardware through the best available platform adapter while keeping the command meaning independent of that adapter. + +The first implementation is Android ARMv7. It reaches the public native Android sensor boundary through the phone's real `libandroid.so` and prints tab-separated metadata. + +A physical Android Go phone has now executed the exact cross-built artifact carried here and returned its real sensor list. The observed run reported `count 0x00000026` and included the phone's accelerometer plus the vendor's gesture/orientation sensors. That device-specific count and those names are evidence from one phone, not values to bake into tests. + +## Phone workflow + +Do not install Clang or the Android NDK on the phone. The phone is an execution target only: fetch the already-built ARMv7 executable, verify it, install it in the Termux command directory, and run `sensors`. + +The repository carries the executable as `sensors.armv7.b64` because this small artifact is stored through a text-content path. After decoding, its SHA-256 is: + +```text +9270b8ebd1243b388a17f24a5cad4883363ca7a5dd122431df2d2a7dc49c87f5 +``` + +It is a 3556-byte ARMv7 Thumb-2 PIE with `/system/bin/linker` as interpreter and `libandroid.so` as its only dynamic library dependency. + +A typical install is: + +```sh +base64 -d sensors.armv7.b64 > "$PREFIX/bin/sensors" +echo '9270b8ebd1243b388a17f24a5cad4883363ca7a5dd122431df2d2a7dc49c87f5 '"$PREFIX/bin/sensors" | sha256sum -c - +chmod 755 "$PREFIX/bin/sensors" +sensors +``` + +## Off-device build + +`sensors.c` is freestanding so the cross-build does not need Android headers or libc. It writes output with ARM Linux system calls and calls only the public Android sensor symbols it needs. + +`link-libandroid-stub.c` is link-time scaffolding only. It supplies symbol names and the `libandroid.so` SONAME to the off-device linker. The stub is not shipped to the phone; Android's dynamic linker loads the phone's real `libandroid.so`. + +The current artifact was produced with Clang/LLD 17: + +```sh +clang --target=armv7a-linux-gnueabi -march=armv7-a -mthumb \ + -ffreestanding -fPIC -fno-stack-protector -fno-builtin -nostdlib \ + -fuse-ld=lld -shared -Wl,-soname,libandroid.so -Wl,--no-undefined \ + -o /tmp/libandroid.so link-libandroid-stub.c + +clang --target=armv7a-linux-gnueabi -march=armv7-a -mthumb -Oz \ + -ffreestanding -fPIE -fno-stack-protector -fno-builtin -nostdlib \ + -c -o /tmp/sensors.o sensors.c + +clang --target=armv7a-linux-gnueabi -fuse-ld=lld -nostdlib \ + -Wl,-pie -Wl,--dynamic-linker=/system/bin/linker -Wl,-e,_start \ + -Wl,--hash-style=both -L/tmp /tmp/sensors.o -landroid -o sensors +``` + +The libc-free formatter is an implementation convenience, not part of the command semantics. The meaningful architectural choice is that the Android implementation uses the native sensor service boundary rather than a vendor HAL or raw kernel device. + +## Command family + +The next hardware commands should keep the same separation between program meaning and platform adapter: + +```text +sensors + enumerate available sensors + +read accelerometer + wait for one fresh acceleration measurement and print it + +watch accelerometer + stream acceleration measurements +``` + +Later adapters may use Linux IIO, a Termux:API bridge, 9P, FUSE, or another native system interface without changing those meanings. + +The ARM/Thumb compiler repository carries the same programs as backend sample targets. A hand-written C oracle or a physically working Android binary is not, by itself, evidence that IdriƧ generated that ARM/Thumb program. From 63ef4094c6b19c1f7fe40be8db5b774e757492d3 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:46:25 -0400 Subject: [PATCH 14/20] Remove obsolete sensor experiment location --- experiments/android-sensors/README.md | 101 -------------------------- 1 file changed, 101 deletions(-) delete mode 100644 experiments/android-sensors/README.md diff --git a/experiments/android-sensors/README.md b/experiments/android-sensors/README.md deleted file mode 100644 index 2d833c0..0000000 --- a/experiments/android-sensors/README.md +++ /dev/null @@ -1,101 +0,0 @@ -# Live Android sensors - -This is the first live Android probe for the proposed Grease hardware namespace. -It deliberately tests the public native Android sensor boundary before adding a -synthetic filesystem, 9P, FUSE, IIO, direct HAL access, or a Termux:API bridge. - -The first program is only `sensors`: enumerate the sensors visible through the -phone's `libandroid` and print tab-separated metadata. This is an Android -experiment, not a Grease execution receipt. - -## Phone workflow - -Do not install a compiler or Android NDK on the phone for this experiment. The -phone is the execution target only: pull the already-built ARMv7 executable, -check it, and run it. - -The repository carries the executable as `sensors.armv7.b64` because GitHub's -text-content path is being used for this small experimental artifact. Decode it -on the phone, mark it executable, verify the recorded SHA-256, and run it. - -The current executable is 3556 bytes and has SHA-256: - -```text -9270b8ebd1243b388a17f24a5cad4883363ca7a5dd122431df2d2a7dc49c87f5 -``` - -It is an ARMv7 Thumb-2 PIE with `/system/bin/linker` as interpreter and one -runtime dependency: the phone's real `libandroid.so`. - -## Cloud build - -`sensors.c` is freestanding so the cross-build does not need Android headers or -libc. It writes output with ARM Linux system calls and calls only the public -Android sensor symbols it needs. - -`link-libandroid-stub.c` is link-time scaffolding only. It gives the host linker -the `libandroid.so` symbol names and SONAME. The stub is not shipped to the -phone; Android's dynamic linker must load the phone's real `libandroid.so`. - -The artifact currently checked in was produced with Clang/LLD 17 using: - -```sh -clang --target=armv7a-linux-gnueabi -march=armv7-a -mthumb \ - -ffreestanding -fPIC -fno-stack-protector -fno-builtin -nostdlib \ - -fuse-ld=lld -shared -Wl,-soname,libandroid.so -Wl,--no-undefined \ - -o /tmp/libandroid.so link-libandroid-stub.c - -clang --target=armv7a-linux-gnueabi -march=armv7-a -mthumb -Oz \ - -ffreestanding -fPIE -fno-stack-protector -fno-builtin -nostdlib \ - -c -o /tmp/sensors.o sensors.c - -clang --target=armv7a-linux-gnueabi -fuse-ld=lld -nostdlib \ - -Wl,-pie -Wl,--dynamic-linker=/system/bin/linker -Wl,-e,_start \ - -Wl,--hash-style=both -L/tmp /tmp/sensors.o -landroid -o sensors -``` - -Host inspection established that the result is a 32-bit ARM EABI5 PIE, its -entry point is Thumb, and its only dynamic library dependency is `libandroid.so`. -That is cross-build evidence only, not Android runtime acceptance. - -## Expected output - -The current minimal formatter uses hexadecimal integers to avoid dragging a C -runtime into the probe. Output has this shape: - -```text -count 0x00000005 -index type min_delay_us name vendor -0x00000000 0x00000001 0x00002710 ... ... -``` - -The exact count, names, vendor strings, types, and delays are device data and -must not be baked into acceptance tests. - -## Acceptance boundary - -The direct path is accepted only after the exact cross-built artifact: - -1. launches on the physical Android phone; -2. resolves the sensor entry points from the phone's real `libandroid.so`; and -3. returns that phone's sensor list. - -A host cross-build, source inspection, emulator result, or Termux:API command -does not substitute for that physical-device result. Conversely, the phone does -not need to compile the source merely to supply runtime acceptance. - -## Next steps after enumeration works - -Add, in order: - -1. one fresh accelerometer sample using the native Android event queue; -2. a continuous accelerometer event stream; -3. the semantic hardware objects that can later be presented as - `/hardware/sensors`, `/hardware/sensors/accelerometer/info`, - `/hardware/sensors/accelerometer/sample`, and - `/hardware/sensors/accelerometer/events`; -4. alternative adapters such as Termux:API, Linux IIO, 9P, or FUSE without - changing those object meanings. - -The Android mechanism is an adapter. It must not define the permanent Grease -hardware semantics merely because it is the first implementation. From 4420dd2e8b6b7ac8a67f873ba7d19a84788a9313 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:46:29 -0400 Subject: [PATCH 15/20] Remove obsolete sensor experiment location --- experiments/android-sensors/link-libandroid-stub.c | 10 ---------- 1 file changed, 10 deletions(-) delete mode 100644 experiments/android-sensors/link-libandroid-stub.c diff --git a/experiments/android-sensors/link-libandroid-stub.c b/experiments/android-sensors/link-libandroid-stub.c deleted file mode 100644 index ecf5770..0000000 --- a/experiments/android-sensors/link-libandroid-stub.c +++ /dev/null @@ -1,10 +0,0 @@ -void *ASensorManager_getInstance(void) { return 0; } -int ASensorManager_getSensorList(void *manager, const void ***list) { - (void)manager; - (void)list; - return 0; -} -const char *ASensor_getName(const void *sensor) { (void)sensor; return 0; } -const char *ASensor_getVendor(const void *sensor) { (void)sensor; return 0; } -int ASensor_getType(const void *sensor) { (void)sensor; return 0; } -int ASensor_getMinDelay(const void *sensor) { (void)sensor; return 0; } From a6ad8b5d474c5f65b0218920fc733943ffc93107 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:46:34 -0400 Subject: [PATCH 16/20] Remove obsolete sensor experiment location --- experiments/android-sensors/sensors.armv7.b64 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 experiments/android-sensors/sensors.armv7.b64 diff --git a/experiments/android-sensors/sensors.armv7.b64 b/experiments/android-sensors/sensors.armv7.b64 deleted file mode 100644 index 0fac04c..0000000 --- a/experiments/android-sensors/sensors.armv7.b64 +++ /dev/null @@ -1 +0,0 @@ -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 \ No newline at end of file From 800120f3b00bc9b4daaa571bd7c75afe677a2b5c Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:46:41 -0400 Subject: [PATCH 17/20] Remove obsolete sensor experiment location --- experiments/android-sensors/sensors.armv7.sha256 | 1 - 1 file changed, 1 deletion(-) delete mode 100644 experiments/android-sensors/sensors.armv7.sha256 diff --git a/experiments/android-sensors/sensors.armv7.sha256 b/experiments/android-sensors/sensors.armv7.sha256 deleted file mode 100644 index 2cfc594..0000000 --- a/experiments/android-sensors/sensors.armv7.sha256 +++ /dev/null @@ -1 +0,0 @@ -9270b8ebd1243b388a17f24a5cad4883363ca7a5dd122431df2d2a7dc49c87f5 sensors From bff185658e341e93aefc881d0932f1a04ee409b4 Mon Sep 17 00:00:00 2001 From: i Date: Fri, 11 Sep 2026 23:46:45 -0400 Subject: [PATCH 18/20] Remove obsolete sensor experiment location --- experiments/android-sensors/sensors.c | 79 --------------------------- 1 file changed, 79 deletions(-) delete mode 100644 experiments/android-sensors/sensors.c diff --git a/experiments/android-sensors/sensors.c b/experiments/android-sensors/sensors.c deleted file mode 100644 index 557e27f..0000000 --- a/experiments/android-sensors/sensors.c +++ /dev/null @@ -1,79 +0,0 @@ -typedef struct ASensorManager ASensorManager; -typedef struct ASensor ASensor; -typedef const ASensor *const *ASensorList; - -extern ASensorManager *ASensorManager_getInstance(void); -extern int ASensorManager_getSensorList(ASensorManager *, ASensorList *); -extern const char *ASensor_getName(const ASensor *); -extern const char *ASensor_getVendor(const ASensor *); -extern int ASensor_getType(const ASensor *); -extern int ASensor_getMinDelay(const ASensor *); - -static long write_bytes(int fd, const char *data, unsigned int count) { - register long r0 __asm__("r0") = fd; - register long r1 __asm__("r1") = (long)data; - register long r2 __asm__("r2") = count; - register long r7 __asm__("r7") = 4; - __asm__ volatile("svc 0" : "+r"(r0) : "r"(r1), "r"(r2), "r"(r7) : "memory"); - return r0; -} - -__attribute__((noreturn)) static void exit_process(int status) { - register long r0 __asm__("r0") = status; - register long r7 __asm__("r7") = 1; - __asm__ volatile("svc 0" : : "r"(r0), "r"(r7) : "memory"); - for (;;) { } -} - -static unsigned int text_length(const char *text) { - unsigned int n = 0; - if (!text) return 0; - while (text[n]) ++n; - return n; -} - -static void write_text(const char *text) { - if (text) write_bytes(1, text, text_length(text)); -} - -static void write_hex(unsigned int value) { - char out[10]; - static const char digits[] = "0123456789abcdef"; - out[0] = '0'; out[1] = 'x'; - for (unsigned int i = 0; i < 8; ++i) { - unsigned int shift = 28 - i * 4; - out[2 + i] = digits[(value >> shift) & 15u]; - } - write_bytes(1, out, 10); -} - -static int run(void) { - ASensorManager *manager = ASensorManager_getInstance(); - if (!manager) { - write_text("sensor manager unavailable\n"); - return 2; - } - - ASensorList list = 0; - int count = ASensorManager_getSensorList(manager, &list); - if (count < 0 || !list) { - write_text("sensor list unavailable\n"); - return 3; - } - - write_text("count\t"); write_hex((unsigned int)count); write_text("\n"); - write_text("index\ttype\tmin_delay_us\tname\tvendor\n"); - for (int i = 0; i < count; ++i) { - const ASensor *sensor = list[i]; - write_hex((unsigned int)i); write_text("\t"); - write_hex((unsigned int)ASensor_getType(sensor)); write_text("\t"); - write_hex((unsigned int)ASensor_getMinDelay(sensor)); write_text("\t"); - write_text(ASensor_getName(sensor)); write_text("\t"); - write_text(ASensor_getVendor(sensor)); write_text("\n"); - } - return 0; -} - -void _start(void) { - exit_process(run()); -} From 0c0c56063bf1c61810fa5511a66ea9737f4f9c2f Mon Sep 17 00:00:00 2001 From: i Date: Mon, 14 Sep 2026 09:13:08 -0400 Subject: [PATCH 19/20] ci: run cpp-spec on GitHub Ubuntu --- .github/workflows/grease-receipt.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/grease-receipt.yml b/.github/workflows/grease-receipt.yml index 35c0dd2..3e85342 100644 --- a/.github/workflows/grease-receipt.yml +++ b/.github/workflows/grease-receipt.yml @@ -7,8 +7,7 @@ on: jobs: cpp-spec: - if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository - runs-on: [self-hosted, linux, debian] + runs-on: ubuntu-24.04 timeout-minutes: 120 steps: - name: Check out Grease and pinned Oils source @@ -16,24 +15,25 @@ jobs: with: submodules: recursive - - name: Verify pinned source and Debian host + - name: Verify pinned source and Ubuntu host shell: bash run: | revision=$(git rev-parse HEAD:source) test "$(git -C source rev-parse HEAD)" = "$revision" . /etc/os-release - test "$ID" = debian + test "$ID" = ubuntu + test "$(uname -m)" = x86_64 echo "Grease source pin: $revision" - echo "Debian: $PRETTY_NAME" + echo "Ubuntu: $PRETTY_NAME" - - name: Prepare native Debian Oils environment + - name: Prepare Oils build environment working-directory: source shell: bash run: | sudo sysctl vm.mmap_rnd_bits=28 soil/worker.sh JOB-dev-setup-debian - - name: Run inherited Oils cpp-spec workload natively + - name: Run inherited Oils cpp-spec workload working-directory: source shell: bash run: | From bd19f30e74b8d727c94fa49ca8673680f4a94fc9 Mon Sep 17 00:00:00 2001 From: i Date: Mon, 14 Sep 2026 09:24:32 -0400 Subject: [PATCH 20/20] ci: use Oils GitHub Ubuntu harness --- .github/workflows/grease-receipt.yml | 43 ++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/.github/workflows/grease-receipt.yml b/.github/workflows/grease-receipt.yml index 3e85342..b5cec56 100644 --- a/.github/workflows/grease-receipt.yml +++ b/.github/workflows/grease-receipt.yml @@ -5,17 +5,25 @@ on: push: branches: [main] +permissions: + contents: read + jobs: cpp-spec: runs-on: ubuntu-24.04 timeout-minutes: 120 + env: + REPO_ROOT: ${{ github.workspace }}/source-worktree steps: - - name: Check out Grease and pinned Oils source + - name: Check out exact Grease head and pinned Oils source uses: actions/checkout@v4 with: + ref: ${{ github.event.pull_request.head.sha || github.sha }} submodules: recursive + persist-credentials: false - - name: Verify pinned source and Ubuntu host + - name: Verify and record the source pin + id: source_pin shell: bash run: | revision=$(git rev-parse HEAD:source) @@ -23,20 +31,31 @@ jobs: . /etc/os-release test "$ID" = ubuntu test "$(uname -m)" = x86_64 - echo "Grease source pin: $revision" + echo "revision=$revision" >> "$GITHUB_OUTPUT" + echo "Grease: $(git rev-parse HEAD)" + echo "Oils source: $revision" echo "Ubuntu: $PRETTY_NAME" - - name: Prepare Oils build environment - working-directory: source + - name: Check out pinned Oils source as standalone worktree + uses: actions/checkout@v4 + with: + repository: isomorphisms/oils + ref: ${{ steps.source_pin.outputs.revision }} + path: source-worktree + persist-credentials: false + + - name: Verify standalone source revision shell: bash - run: | - sudo sysctl vm.mmap_rnd_bits=28 - soil/worker.sh JOB-dev-setup-debian + run: test "$(git -C source-worktree rev-parse HEAD)" = "${{ steps.source_pin.outputs.revision }}" + + - name: Fix kernel mmap rnd bits + run: sudo sysctl vm.mmap_rnd_bits=28 - - name: Run inherited Oils cpp-spec workload - working-directory: source + - name: Run and verify inherited Oils cpp-spec oracle + working-directory: source-worktree shell: bash run: | - . build/dev-shell.sh - soil/worker.sh JOB-cpp-spec + podman --version + soil/github-actions.sh run-job cpp-spec podman + test "$(cat _tmp/soil/commit-hash.txt)" = "${{ steps.source_pin.outputs.revision }}" soil/host-shim.sh did-all-succeed cpp-spec