Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .agents/skills/develop-maple/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ description: Develop and debug ordinary non-Agent-Mode Maple features and fixes

Work from the `MaplePrivacyLabs/Maple` repository root. Treat `justfile`, `apps/maple-research/frontend/package.json`, `flake.nix`, `scripts/ci/`, and `.github/workflows/` as the command sources of truth. Check them again when they disagree with prose documentation.

The standalone hosted native sign-in application lives in `apps/maple-auth`.
For that app, follow its own `AGENTS.md`, package scripts, and Auth CI scripts;
do not place its code in Research or make Auth depend on Research source,
configuration, or dependency installation. Research retains its built-in auth.

## Route Specialized Work

- Use `$validate-maple` for full validation, packaged-app smoke tests, cross-platform builds, or release-artifact verification.
Expand Down
13 changes: 13 additions & 0 deletions .agents/skills/release-maple/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,19 @@ pinning those consumers first; an intentional local-source release can proceed
with the exact monorepo commit recorded. Unrelated SDK source changes do not
require a pinned client to upgrade, and this preference adds no release gate.

When preparing an enclave trust or PCR rotation change, review both browser
consumers' embedded fallbacks against the approved development and production
histories: `apps/maple-research/frontend/src/config/openSecretClientConfig.ts`
and `apps/maple-auth/src/config/openSecretClientConfig.ts`. Verify each affected
app's combined app-provided and pinned-SDK roots support its intended approved
enclave measurements when signed-history fetching is unavailable, preserving
development/production separation. Record affected artifacts and any pending rollout
in the handoff. Auth owns a separate SDK pin and publisher: refreshing Research
does not update Auth, and an Auth publication remains a separately authorized
operation under [the Pages guide](../../../docs/pages-deployments.md#independent-auth-site).
This is a compatibility review of each consumer, not a requirement to keep their
lists byte-identical or release them together.

Record the proxy version and inspect its own runtime inputs since `previous_tag`:

```bash
Expand Down
17 changes: 17 additions & 0 deletions .agents/skills/validate-maple/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,23 @@ Use for iOS, Android, signing, updater metadata, installers, entitlements, or di

Run commands from the repository root unless the command changes directory explicitly.

### Standalone hosted Auth

For changes confined to `apps/maple-auth`, use its own guide and checks:

```bash
nix develop --no-update-lock-file .#ci -c ./scripts/ci/auth-ci.sh
MAPLE_AUTH_ENVIRONMENT=pr nix develop --no-update-lock-file .#ci -c ./scripts/ci/auth-web.sh
```

Auth owns its package, registry SDK pin, frozen lockfile, tests, assets, and
`dist` build. Do not install Research dependencies or run its web/native
packaging merely to validate Auth. Shared publisher/workflow changes still
require the repository checks. Real provider callbacks, retained sessions,
manual/native opening, and live edge behavior require separate rehearsal;
a local artifact does not establish those results. Browser smoke must serve
Auth's built `dist` with its own preview command and record its origin.

### Focused frontend test

```bash
Expand Down
3 changes: 3 additions & 0 deletions .githooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ fi
if hook_selected research_frontend || hook_selected research_rust; then
run_component maple-research "$REPO_ROOT" ".#ci" "$REPO_ROOT/apps/maple-research/.githooks/pre-commit"
fi
if hook_selected auth; then
run_component maple-auth "$REPO_ROOT" ".#ci" "$REPO_ROOT/apps/maple-auth/.githooks/pre-commit"
fi
if hook_selected updates; then
run_component updates "$REPO_ROOT" ".#ci" "$REPO_ROOT/services/updates/.githooks/pre-commit"
fi
Expand Down
3 changes: 2 additions & 1 deletion .githooks/repo-checks
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ workflows=$(hook_staged_matching '^\.github/workflows/.*\.ya?ml$')
if [ -n "$workflows" ]; then
hook_require actionlint
for workflow in $workflows; do
if [ "$workflow" = ".github/workflows/pages-publish.yml" ]; then
if [ "$workflow" = ".github/workflows/pages-publish.yml" ] ||
[ "$workflow" = ".github/workflows/auth-pages-publish.yml" ]; then
hook_run actionlint -config-file .github/actionlint.yaml \
-ignore 'unexpected key "deployment" for "environment" section' "$workflow"
else
Expand Down
57 changes: 57 additions & 0 deletions .github/workflows/auth-pages-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Auth Pages build

permissions:
contents: read

on:
workflow_dispatch:

jobs:
build:
if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest-8-cores
timeout-minutes: 30
steps:
- name: Checkout auth source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
ref: ${{ github.sha }}
persist-credentials: false

- name: Install Nix
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22
with:
github-token: ""

- name: Test Pages artifact and deployment boundaries
run: nix build --no-update-lock-file --no-link --print-build-logs .#checks.x86_64-linux.pages

- name: Test the standalone auth app
run: nix develop --no-update-lock-file .#ci -c bash scripts/ci/auth-ci.sh

- name: Build auth with production services
env:
MAPLE_AUTH_ENVIRONMENT: release
run: nix develop --no-update-lock-file .#ci -c bash scripts/ci/auth-web.sh

- name: Describe the auth artifact
run: |
set -euo pipefail
artifact_dir="apps/maple-auth/target/reproducibility"
nix develop --no-update-lock-file .#pages -c python3 -I scripts/ci/pages_artifact.py manifest \
--archive "$artifact_dir/maple-auth-dist.tar.gz" \
--profile auth-release \
--sha "$GITHUB_SHA" \
--run-id "$GITHUB_RUN_ID" \
--run-attempt "$GITHUB_RUN_ATTEMPT" \
--output "$artifact_dir/pages-artifact.json"

- name: Upload the auth artifact
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: maple-auth-production-${{ github.run_id }}-${{ github.run_attempt }}
path: |
apps/maple-auth/target/reproducibility/maple-auth-dist.tar.gz
apps/maple-auth/target/reproducibility/pages-artifact.json
if-no-files-found: error
retention-days: 5
57 changes: 57 additions & 0 deletions .github/workflows/auth-pages-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Auth Pages CI

permissions:
contents: read

on:
pull_request:
# Include stacked PRs and forks; this job has no publishing authority.
paths:
- ".github/workflows/auth-pages-*.yml"
- ".github/workflows/pages-tests.yml"
- "apps/maple-auth/**"
- "scripts/ci/auth-*.sh"
- "scripts/ci/pages_*.py"
- "scripts/ci/test_pages_*.py"
- "flake.nix"
- "flake.lock"
push:
branches: [master]
paths:
- ".github/workflows/auth-pages-*.yml"
- ".github/workflows/pages-tests.yml"
- "apps/maple-auth/**"
- "scripts/ci/auth-*.sh"
- "scripts/ci/pages_*.py"
- "scripts/ci/test_pages_*.py"
- "flake.nix"
- "flake.lock"

jobs:
auth:
if: >-
github.event_name == 'pull_request' ||
(github.event_name == 'push' && github.ref == 'refs/heads/master')
runs-on: ubuntu-latest-8-cores
timeout-minutes: 30
steps:
- name: Checkout auth source
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
persist-credentials: false

- name: Install Nix
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22
with:
github-token: ""

- name: Test Pages artifact and deployment boundaries
run: nix build --no-update-lock-file --no-link --print-build-logs .#checks.x86_64-linux.pages

- name: Test the standalone auth app
run: nix develop --no-update-lock-file .#ci -c bash scripts/ci/auth-ci.sh

- name: Build auth with development services
env:
MAPLE_AUTH_ENVIRONMENT: pr
run: nix develop --no-update-lock-file .#ci -c bash scripts/ci/auth-web.sh
69 changes: 69 additions & 0 deletions .github/workflows/auth-pages-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
name: Publish Auth Pages

permissions:
contents: read

on:
workflow_dispatch:
inputs:
build_run_id:
description: Successful Auth Pages build run ID
required: true
type: string
build_run_attempt:
description: Successful Auth Pages build run attempt
required: true
type: string

jobs:
production:
name: Publish verified auth build
if: >-
vars.MAPLE_AUTH_PAGES_PRODUCTION_ENABLED == 'true' &&
github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/master'
runs-on: ubuntu-latest
timeout-minutes: 20
concurrency:
group: pages-auth-production
cancel-in-progress: false
environment:
name: auth-pages-production
# Explicit artifact-SHA deployment status owns the production URL.
deployment: false
permissions:
contents: write
actions: read
deployments: write
steps:
- name: Checkout trusted publisher
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
ref: ${{ github.sha }}
persist-credentials: false

- name: Install Nix
uses: DeterminateSystems/nix-installer-action@ef8a148080ab6020fd15196c2084a2eea5ff2d25 # v22
with:
github-token: ""

- name: Install trusted deployment dependencies
working-directory: services/updates
run: nix develop --no-update-lock-file ../..#pages -c bun install --frozen-lockfile --ignore-scripts

- name: Verify and prepare the auth artifact
env:
GH_TOKEN: ${{ github.token }}
MAPLE_AUTH_PAGES_PRODUCTION_ENABLED: ${{ vars.MAPLE_AUTH_PAGES_PRODUCTION_ENABLED }}
run: >-
nix develop --no-update-lock-file .#pages -c python3 -I scripts/ci/pages_auth_deploy.py
prepare --state "$RUNNER_TEMP/maple-auth-pages"

- name: Deploy the verified auth artifact
env:
GH_TOKEN: ${{ github.token }}
MAPLE_AUTH_PAGES_PRODUCTION_ENABLED: ${{ vars.MAPLE_AUTH_PAGES_PRODUCTION_ENABLED }}
CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }}
run: >-
nix develop --no-update-lock-file .#pages -c python3 -I scripts/ci/pages_auth_deploy.py
deploy --state "$RUNNER_TEMP/maple-auth-pages"
4 changes: 4 additions & 0 deletions .github/workflows/pages-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,12 @@ on:
pull_request:
paths:
- ".github/workflows/pages-*.yml"
- ".github/workflows/auth-pages-*.yml"
- "scripts/ci/pages_*.py"
- "scripts/ci/test_pages_*.py"
- "scripts/ci/_common.sh"
- "scripts/ci/web.sh"
- "scripts/ci/auth-*.sh"
- "services/updates/package.json"
- "services/updates/bun.lock"
- "flake.nix"
Expand All @@ -19,10 +21,12 @@ on:
branches: [master]
paths:
- ".github/workflows/pages-*.yml"
- ".github/workflows/auth-pages-*.yml"
- "scripts/ci/pages_*.py"
- "scripts/ci/test_pages_*.py"
- "scripts/ci/_common.sh"
- "scripts/ci/web.sh"
- "scripts/ci/auth-*.sh"
- "services/updates/package.json"
- "services/updates/bun.lock"
- "flake.nix"
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ apps/maple-research/frontend/node_modules/

# Build outputs
/apps/maple-research/frontend/dist/
/apps/maple-auth/dist/
/apps/maple-auth/target/
/apps/maple-research/frontend/build/

# Environment variables
Expand Down
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ current source and tests take precedence over historical design documents.
- `apps/maple-research/`: the existing React/Vite/Tauri Maple application,
including desktop Agent Mode. Read its [guide](apps/maple-research/AGENTS.md)
for runtime placement, native security, and exact-app validation.
- `apps/maple-auth/`: standalone V2 hosted native sign-in, with its own
package, SDK pin, tests, build, and independent Pages publisher. Read its
[guide](apps/maple-auth/AGENTS.md). Research keeps its built-in auth; do not
introduce cross-app source imports or coupled release triggers.
- `apps/maple-agent/`: GPUI desktop-v2 prototype, ACP and proxy CLI. Read its
[guide](apps/maple-agent/AGENTS.md) and `$develop-maple-agent`. Its runtime and
update discovery are separate from Research and its existing Agent Mode.
Expand Down Expand Up @@ -97,7 +101,7 @@ release-configuration changes, plus the affected component checks.
`./setup-hooks.sh` installs `.githooks/pre-commit`. It classifies staged paths
with `scripts/ci/hook_change_detection.py` and runs each affected component's
own `.githooks/pre-commit` inside that component's Nix flake, so the tools match
CI: the root `.#ci` shell for Research, `services/updates/`, and repository
CI: the root `.#ci` shell for Research, Auth, `services/updates/`, and repository
checks; the component flakes for `apps/maple-agent/`, `sdk/`, `proxy/`, and
`services/opensecret?submodules=1`. Without Nix it runs the same commands from
`PATH` and warns that results may differ. It runs formatters, Clippy/ESLint,
Expand Down
5 changes: 5 additions & 0 deletions apps/maple-auth/.githooks/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env sh
set -eu
component_dir=$(CDPATH= cd -- "$(dirname -- "$0")/.." && pwd)
repo_root=${MAPLE_HOOK_REPO_ROOT:-$(CDPATH= cd -- "$component_dir/../.." && pwd)}
exec bash "$repo_root/scripts/ci/auth-ci.sh"
6 changes: 6 additions & 0 deletions apps/maple-auth/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
node_modules/
dist/
target/
*.tsbuildinfo
.env*
!.env.example
5 changes: 5 additions & 0 deletions apps/maple-auth/.prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
node_modules
dist
target
bun.lock
*.tsbuildinfo
7 changes: 7 additions & 0 deletions apps/maple-auth/.prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": true,
"singleQuote": false,
"trailingComma": "none",
"tabWidth": 2,
"printWidth": 100
}
27 changes: 27 additions & 0 deletions apps/maple-auth/AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Maple auth app guide

Read the root guide and `$review-maple-security` for authentication changes.
This application is independent of Research: use its own package.json,
bun.lock, source, public assets, and config. Do not import sibling app files,
parent node_modules, or local SDK source. Consume the exact published SDK pin.
An auth-only change must not alter Research web authentication or client entry
URLs.

Use the root `.#ci` Nix shell (Bun and Node match CI). See [README.md](README.md)
for development, component checks and the two fixed build profiles. Run
`scripts/ci/auth-ci.sh` for format, lint, type checking, and tests. The root hook
routes this app to `.githooks/pre-commit`. Run the auth build when source,
configuration or dependencies change, and root `nix flake check` for workflow
or shared CI changes. Do not overwrite ignored environment files.

Preserve V2-only route parsing, same-origin OAuth callbacks, popup-only Apple,
SDK bootstrap ordering, pending target and account ownership checks, one mint
per confirmation, and the manual Open Maple link. Handoff completion clears
only its pending flow; it does not clear SDK credentials. Do not log provider
codes, state, tokens, handoff grants or credential-bearing URLs. Keep storage,
crypto and backend authority in the SDK and OpenSecret.

The build boundary must reject sibling app code, linked SDK source and the
legacy SDK. Preserve the unprivileged build and trusted independent publisher.
A merge or successful build does not authorize publication or redirects.
Report automated checks separately from real provider/native/browser testing.
Loading
Loading