docs: add gemini.md guidelines

Add gemini.md containing project guidelines for the Gemini coding
assistant.

Tested: N/A

Change-Id: I5c0669fc49af7cd38f621678b5bef5d815cd4789
Signed-off-by: Hao Jiang <jianghao@google.com>
diff --git a/build.md b/build.md
new file mode 100644
index 0000000..6902b21
--- /dev/null
+++ b/build.md
@@ -0,0 +1,30 @@
+## Compile and Test Environment
+
+If the Antigravity/Gemini console/server is not running in the OpenBMC unittest
+container, all compile and testing tasks should be redirected to the container.
+**Always use the `openbmc/ubuntu-unit-test` Docker container for all build and
+test commands.** Otherwise, directly start the task on the bare server, given it
+has been in the container.
+
+Always compile and run tests in the Docker container.
+
+Use `.vscode/settings.json` and `.devcontainer/devcontainer.json` to setup the
+docker environment.
+
+## Meson Configuration
+
+To configure Meson inside the OpenBMC unit test container, run the following
+command from the workspace root:
+
+```bash
+docker run --rm -v "${PWD}:/ws" -w /ws openbmc/ubuntu-unit-test:2025-W36-725b9a7cb31b8fdf meson setup build_docker
+```
+
+## Object Mapper Setup
+
+To run the real Object Mapper (`mapperx`) inside the OpenBMC unit test
+container, use the following command in a separate terminal:
+
+```bash
+docker run --rm -v "${PWD}:/ws" -w /ws openbmc/ubuntu-unit-test:2025-W36-725b9a7cb31b8fdf bash -c "LD_LIBRARY_PATH=/usr/local/lib/x86_64-linux-gnu/:/usr/local/lib/ /usr/local/libexec/phosphor-objmgr/mapperx --service-namespaces='xyz.openbmc_project' --interface-namespaces='xyz.openbmc_project'"
+```
diff --git a/gemini.md b/gemini.md
new file mode 100644
index 0000000..14d55db
--- /dev/null
+++ b/gemini.md
@@ -0,0 +1,109 @@
+# Gemini Coding Assistant Project Guidelines
+
+## High-Level Flow
+
+Follow the following flow to implement any feature. Refer to each chapter of
+this document for detailed guidelines.
+
+1. Understand the requirements and Design the solution
+2. Implement the solution and test it
+3. Commit the code changes
+
+Agent should not skip to next step without explicit permission from user.
+
+## Understand the requirements and Design the solution
+
+AI Agents should start in the design mode. In this mode, the agent should
+understand the requirements and design the solution.
+
+Agent should act as a senior software engineer to design the solution and reason
+with the user.
+
+Agent should use the following source as reference:
+
+- workspace files
+- Use the build.md to configure the Meson. Use the `subprojects` directory.
+- Refer to the docker system file for include headers.
+
+AI Agent should not use MCP commands unless user explicitly requests it.
+
+The implementation plan should consist of the following:
+
+- High level design
+  - when my requirements are ambiguous, first ask, don't guess.
+- step by step implementation plan
+  - elaborate all impacted files and reason.
+- test cases
+
+AI Agent should save the implementation plan in the temporary markdown file.
+
+## Implement the solution and test it
+
+AI Agents should start in the implementation mode. In this mode, the agent
+should implement the solution and test it.
+
+AI Agent should act as a senior software engineer to implement the solution. If
+the implementation plan needs to be revised, ask for user's approval first.
+
+AI Agent should compile the code in the docker container based on `build.md` and
+make sure the code compiles successfully.
+
+AI Agent should use `.clang-format` to format the code before compiling.
+
+AI Agent should create all unit tests under `tests/` directory. Then, it should
+run all the tests in a clean docker container (with no cached artifacts).
+
+If any unit test case fails, fix it and recompile, and test again. Agent should
+not run shortcut and alter the test cases in the plan.
+
+Setup a subagent based on the implementation plan and lesson.md file to review
+the code changes.
+
+## Local Presubmit and Commit
+
+Before commit, run local presubmit test:
+
+- Create a dummy commit (`git commit -m "temp: strip shmem"`) removing `shared_mem_dep` and `absl_status_dep` in root `meson.build`.
+- Copy `common_clang_tidy_config.yaml` from Google3 Kokoro platform configs into the workspace root.
+- Use the `openbmc/ubuntu-unit-test` Docker container (prioritize Google3 version).
+- Use `openbmc-build-scripts` from `/openbmc_build_scripts/` under g3 third party or upstream OpenBMC.
+- Run `run-unit-test-docker.sh` inside the docker container w/ `-c 1`.
+- Drop dummy commit w/ `git reset --hard HEAD~1` upon completion.
+
+Ask the user to provide the bug id.
+
+The commit message should follow the OpenBMC git format:
+
+- Title: `subsystem: short description` (<= 50 chars).
+- Blank line.
+- Body: Detailed explanation of why and what, wrapped at 72 chars.
+- Footer: `Tested: <brief test performed>`
+- Footer: `Google-Bug-Id: <bug id>`
+- Footer: `Signed-off-by: Name <email>`
+
+**Guidelines for Content:**
+
+- **Highlight the Generic Idea**: Focus on the bug fix or the core feature.
+  Explain the high-level design decisions.
+- **Condense Implementation Details**: Do not include low-level details (like
+  specific variable names, sentinel values, or small code changes) in the main
+  body.
+- **Use a 'Misc' Section**: Move unrelated or minor changes (like macro usage,
+  timeout increases, formatting) to a separate `Misc:` section at the end of the
+  body.
+
+For example:
+
+```text
+benchmark: refine control plane benchmarks
+
+Refined the control plane benchmarks to use full device paths in Flatten
+model keys and 'contains'/'contained_by' edges in Graph model.
+
+Signed-off-by: Hao Jiang <jianghao@google.com>
+```
+
+Using `@mcp:buganizer:` to upload the implmenetation plan to the bug.
+
+- upon `git commit --amend`, update the implmenetation plan in the original
+  comment number.
diff --git a/lesson.md b/lesson.md
new file mode 100644
index 0000000..ca3116f
--- /dev/null
+++ b/lesson.md
@@ -0,0 +1,47 @@
+## C++ Best Practices
+
+### State Machine for Asynchronous Queries
+
+When dealing with asynchronous D-Bus queries that can be triggered by external
+events (like `InterfacesAdded`), use a state machine to handle race conditions
+and defer events:
+
+- Use a `querying` boolean flag to protect the critical section during an active
+  query.
+- Use an enum state (e.g., `None`, `Add`, `Remove`) to record events that arrive
+  _while_ a query is in flight.
+- When the query completes, check the recorded state and trigger a deferred
+  query if needed (e.g., if an `Add` event arrived).
+- Centralize the setting and clearing of the `querying` flag inside the query
+  function to avoid scattered state management.
+
+### Compare, Don't Subtract for Sentinel Time Points
+
+Because of the guaranteed overflow, you should never perform arithmetic
+operations on `time_point::min()` or `time_point::max()`. They are strictly
+meant to be used as sentinel (flag) values.
+
+If you need to know if an interval is valid, use equality operators (`==` or
+`!=`) to check the state of the variable before doing any math:
+
+```cpp
+auto last_event = std::chrono::steady_clock::time_point::min();
+auto current_time = std::chrono::steady_clock::now();
+
+// ❌ WRONG: This will overflow and cause undefined behavior!
+// auto elapsed = current_time - last_event;
+
+// ✅ CORRECT: Check the sentinel value first
+if (last_event != std::chrono::steady_clock::time_point::min()) {
+    auto elapsed = current_time - last_event;
+    // Process the elapsed time...
+}
+
+## Testing & Debugging
+
+### Verify Mock Before Questioning Infrastructure
+Before questioning Object Mapper (mapperx) performance or behavior in a testing environment, use `dbus-monitor` and `busctl` to examine the mock server implementation. The mock might be static or missing dynamic behaviors expected by the test.
+
+### Use A/B Testing for Regressions
+Use A/B testing (running specific tests with and without your changes) to narrow down which change broke what test, before claiming the test was already failing before your changes.
+```