@odla-ai/cli 0.22.0 → 0.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -37,6 +37,26 @@ npx @odla-ai/cli runbook list # what exists
37
37
  Reading works for any signed-in developer and needs no `odla.config.mjs` — the
38
38
  advice is most useful before there is a project.
39
39
 
40
+ Runbooks tell an agent how to operate; PM tells every agent what this project is
41
+ trying to prove, what is active, what was decided, and what is broken. Once the
42
+ app is registered, start each session by reading its doing tasks, open bugs and
43
+ goals, and recent decisions:
44
+
45
+ ```bash
46
+ npx odla-ai pm task list --app <appId> --column doing
47
+ npx odla-ai pm bug list --app <appId> --status open
48
+ npx odla-ai pm goal list --app <appId> --status open
49
+ npx odla-ai pm decision list --app <appId> --limit 20
50
+ ```
51
+
52
+ Read the active task, linked goal, and comments before changing code. Without
53
+ `--app`, list commands span every project the account co-owns, which is the
54
+ right first view when coordinating several efforts; scope every write to the
55
+ exact `appId` from that project's config. PM requires a registered app. Before
56
+ the first provision, use a focused commit/checkpoint, then initialize PM and
57
+ backfill that evidence immediately after registration. Never use a parallel
58
+ status diary or put a secret in PM.
59
+
40
60
  **Runbooks are procedure; JSDoc is API.** What a function takes, returns, and
41
61
  guarantees is documented on the export itself, ships in the installed
42
62
  `.d.ts`, and renders per package at <https://odla.ai/docs>. A runbook will tell
@@ -93,11 +113,14 @@ npx @odla-ai/cli init --app-id my-app --name "My App"
93
113
  ```
94
114
 
95
115
  For a project you keep working in, install it as a dev dependency so the
96
- shorter `npx odla-ai` form works and the version is pinned by your lockfile:
116
+ shorter `npx odla-ai` form works. ODLA is under active development: use a normal
117
+ dependency declaration, commit the lockfile, and let `npm ci` reproduce the
118
+ resolved graph:
97
119
 
98
120
  ```bash
99
- npm view @odla-ai/cli@0.16.6 version
100
- npm i -D --save-exact @odla-ai/cli@0.16.6
121
+ npm view @odla-ai/cli version
122
+ npm i -D @odla-ai/cli
123
+ npm ls @odla-ai/cli
101
124
  ```
102
125
 
103
126
  ## Prerequisites
@@ -360,8 +383,8 @@ rolling-window/age-out, quota-backoff, retention/purge, or provider-derived
360
383
  mutation-id control. Public health remains aggregate rather than per calendar.
361
384
 
362
385
  The bundled build/migration skills add a passive pre-ship gate with
363
- `@odla-ai/security`: after the exact-version availability check, run
364
- `npm i -D --save-exact @odla-ai/security@0.3.1`, then
386
+ `@odla-ai/security`: install it with a normal development range, commit the
387
+ lockfile, then run `npm i -D @odla-ai/security`, followed by
365
388
  `npx odla-security scan . --profile odla --out .odla/security/pre-ship --fail-on high --fail-on-candidates critical`.
366
389
  The passive scan remains a separate binary: it makes no model calls and does
367
390
  not execute target code. After explicit redacted-source approval,
@@ -385,12 +408,11 @@ a conservative `Retry-After`. A provider-side `429` uses the sanitized
385
408
  carries a bounded `Retry-After` only when the upstream supplied one. The CLI
386
409
  does not echo arbitrary response text or silently change the admin-selected
387
410
  model.
388
- Before installing the exact release, require
389
- `npm view @odla-ai/security@0.3.1 version` to succeed before installation. An
390
- exact-version `E404` means the release is unavailable, not that the security
391
- preflight passed, and does not prove the package name is absent. odla's own
392
- engineering environment uses an equivalent internal gate; customer projects
393
- should use the published `odla-security` command above.
411
+ Confirm `npm view @odla-ai/security version` succeeds and record the installed
412
+ version from `npm ls @odla-ai/security` with the scan evidence. A registry
413
+ failure blocks the preflight; it is not a clean scan. odla's own engineering
414
+ environment uses an equivalent internal gate; customer projects should use the
415
+ published `odla-security` command above.
394
416
 
395
417
  For a server-side, commit-pinned review, connect one repository through the
396
418
  source-read-only odla GitHub App. The CLI infers `owner/name` from a safe GitHub HTTPS
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@odla-ai/cli",
3
- "version": "0.22.0",
3
+ "version": "0.22.1",
4
4
  "description": "Agent-operable CLI for odla provisioning, calendar consent and sync lifecycle, System AI administration, Worker secrets, security jobs, and smoke checks.",
5
5
  "license": "MIT",
6
6
  "homepage": "https://odla.ai/docs/packages/cli",
@@ -141,13 +141,19 @@ guessing which platform/credential steps need manual work. Then:
141
141
 
142
142
  odla has a project manager for agents — conformance goals, a kanban board, a
143
143
  decision log, and bugs, shared with the human and with every other agent working
144
- on the app. It is platform-side: nothing to install or provision. Start a session
145
- by reading it, and keep it current while you build:
144
+ on the app. It is platform-side: there is nothing PM-specific to install or
145
+ provision. Start a session by reading it, and keep it current while you build:
146
146
 
147
147
  ```cmd
148
148
  npx @odla-ai/cli pm task list --app <appId> --column doing
149
149
  ```
150
150
 
151
+ The app must already be registered for ownership-scoped PM access. On a new
152
+ project, use a focused commit/checkpoint only until the first provision, then
153
+ initialize PM and backfill the approved early evidence immediately. Across
154
+ several efforts, list without `--app` first, then scope every write to the exact
155
+ project id.
156
+
151
157
  Record a **decision** the moment you make one (with what it rules out), file a
152
158
  **bug** the moment you notice one, and move a **task** when the work moves. A
153
159
  decision you don't record is one the next agent re-litigates. Full command set,
@@ -101,13 +101,14 @@ helpers (`computeBookableSlots`, formatters), never the admin key.
101
101
 
102
102
  Install the passive harness and scan before any production secret or deploy:
103
103
 
104
- Before installing the exact release, first verify
105
- `npm view @odla-ai/security@0.3.1 version`. An exact-version `E404` means the
106
- release is unavailable and blocks this preflight; it is not a clean scan and
107
- does not prove the package name is absent.
104
+ First verify `npm view @odla-ai/security version`. A registry failure blocks
105
+ this preflight; it is not a clean scan. Use a normal dependency declaration
106
+ while ODLA is under active development, commit the lockfile, and record the
107
+ resolved version with the scan evidence.
108
108
 
109
109
  ```
110
- npm i -D --save-exact @odla-ai/security@0.3.1
110
+ npm i -D @odla-ai/security
111
+ npm ls @odla-ai/security
111
112
  npx odla-security scan . --profile odla --out .odla/security/pre-ship --fail-on high --fail-on-candidates critical
112
113
  ```
113
114
 
@@ -11,8 +11,8 @@ only mention in chat is a bug nobody fixes.
11
11
  ## What it is, mechanically
12
12
 
13
13
  - PM data lives on the **platform**, in odla's own shared store — *not* in the
14
- app's database. There is nothing to install, schema, or provision, and no
15
- entry in `odla.config.mjs`.
14
+ app's database. There is no PM schema or integration to install, but the
15
+ project app must already be registered so ownership can scope access.
16
16
  - Every item is tagged with an **appId**, and access rides **app co-ownership**:
17
17
  you see and write PM items for exactly the apps you co-own
18
18
  (`references/co-owners.md`). Co-own three apps and one `pm bug list` spans all
@@ -24,6 +24,12 @@ only mention in chat is a bug nobody fixes.
24
24
  app's **Project** tab in Studio): the board is drag-and-drop there, and every
25
25
  section filters by project.
26
26
 
27
+ For a brand-new app, use a focused branch/commit and a clear checkpoint handoff
28
+ only until the first successful `provision` registers it. Then initialize PM
29
+ immediately and backfill the approved early decisions and evidence. Never use
30
+ an unrelated app as a temporary PM bucket, and never keep a parallel project
31
+ diary after PM is available.
32
+
27
33
  ## The four things, and when each one is right
28
34
 
29
35
  | You have | File it as | Because |
@@ -82,8 +88,16 @@ npx @odla-ai/cli pm task list --app <appId> --column doing
82
88
  ```
83
89
 
84
90
  then `pm bug list --app <appId> --status open` and
85
- `pm decision list --app <appId> --limit 10`. That is the state of the project in
86
- three commands including anything a *different* agent left behind.
91
+ `pm decision list --app <appId> --limit 10`, plus
92
+ `pm goal list --app <appId> --status open`. Read the active task, linked goal,
93
+ and their comments. That is the state of the project—including anything a
94
+ *different* agent left behind.
95
+
96
+ When coordinating several efforts, begin without `--app` to see doing tasks and
97
+ open bugs across every co-owned project, then scope each write to the exact
98
+ `appId` from that project's `odla.config.mjs`. Parallel agents should own
99
+ different board tasks and different branches/worktrees; they coordinate through
100
+ goal links and comments rather than sharing a working tree or status document.
87
101
 
88
102
  **While you build:**
89
103
 
@@ -137,13 +137,13 @@ in sync.
137
137
  Run the passive CLI in local/CI development; do not import it into the running
138
138
  Worker:
139
139
 
140
- Before installing the exact release, require
141
- `npm view @odla-ai/security@0.3.1 version` to succeed before installing it. An
142
- exact-version `E404` means the release is unavailable, not that the preflight
143
- passed, and does not prove the package name is absent.
140
+ Require `npm view @odla-ai/security version` to succeed before installing it.
141
+ A registry failure blocks the preflight; it is not a clean scan. Use a normal
142
+ dependency declaration, commit the lockfile, and record the resolved version.
144
143
 
145
144
  ```
146
- npm i -D --save-exact @odla-ai/security@0.3.1
145
+ npm i -D @odla-ai/security
146
+ npm ls @odla-ai/security
147
147
  npx odla-security scan . --profile odla --out .odla/security/pre-ship --fail-on high --fail-on-candidates critical
148
148
  ```
149
149
 
@@ -6,6 +6,7 @@ description: >
6
6
  move a static or GitHub Pages site to Cloudflare/odla, or to add a backend,
7
7
  database, login/auth, or AI features to a static site via odla.
8
8
  runbookOrder:
9
+ - references/project-state.md
9
10
  - references/phase-0-preflight.md
10
11
  - references/phase-1-static.md
11
12
  - references/phase-2-db.md
@@ -60,6 +61,9 @@ installed skill at `../odla/SKILL.md` instead.
60
61
  endpoints. An old public embed link is not a booking flow; preserve it via
61
62
  `bookingPageUrl` only until the native flow is verified. Google OAuth
62
63
  tokens never enter the repo, CLI, or chat.
64
+ 8. Project state belongs in odla PM, not a migration diary in the source tree.
65
+ Read `references/project-state.md` before recording or resuming work. Never
66
+ put credentials or secret values in PM.
63
67
 
64
68
  ## Phase state machine
65
69
 
@@ -68,10 +72,11 @@ Phases run strictly in order; each has a verification gate:
68
72
  P0 preflight -> P1 static-on-cloudflare -> P2 database -> P2b calendar (optional) -> P3 login
69
73
  -> P4 ai (optional) -> P5 prod + DNS cutover
70
74
 
71
- `MIGRATION.md` at the user's repo root is the durable state: create it in
72
- Phase 0, update it at every gate (phase, what changed, what was verified).
73
- In a fresh session, read MIGRATION.md first and resume from the recorded
74
- phase; `npx @odla-ai/cli doctor` confirms the current config state.
75
+ PM is the durable state: goals define the migration gates, board tasks show the
76
+ active phase, decisions preserve product and architecture choices, bugs capture
77
+ defects, and comments carry evidence. In a fresh session, query PM first as
78
+ specified in `references/project-state.md`; `npx @odla-ai/cli doctor` then
79
+ confirms the checked-in config state.
75
80
 
76
81
  ## Auth model (one line)
77
82
 
@@ -116,6 +121,7 @@ so this is a natural first step.
116
121
  Read the current phase's file when you enter it — not before:
117
122
 
118
123
  - references/phase-0-preflight.md
124
+ - references/project-state.md (read before Phase 0 and at every session start)
119
125
  - references/phase-1-static.md
120
126
  - references/phase-2-db.md
121
127
  - references/phase-2b-calendar.md (optional: live Google Calendar booking — slots, create/reschedule/cancel through the app's own Worker)
@@ -31,16 +31,19 @@ Human obligation: none.
31
31
  `sk_live_`, `whsec_`, `ghp_`, `github_pat_`, `AKIA`, `-----BEGIN`).
32
32
  Any hit: STOP, show the human file:line (never the value), and
33
33
  resolve before continuing.
34
- 5. Create `MIGRATION.md` at the repo root: the six-phase checklist with
35
- P0 marked in progress, the inventory findings, and the chosen build
36
- dir. Commit it (review `git status` first).
34
+ 5. Choose the intended stable odla `appId`. Follow
35
+ `project-state.md`'s pre-registration bootstrap: keep the inventory and
36
+ evidence in focused source-controlled artifacts/commits and the checkpoint
37
+ handoff. Do not create a parallel migration diary. PM becomes authoritative
38
+ immediately after Phase 2 registers the app.
37
39
 
38
40
  ## Verification checklist
39
41
 
40
42
  - [ ] Build runs clean and populates only the dedicated output dir
41
43
  - [ ] Output dir contains index.html and the site's assets
42
44
  - [ ] No committed secrets found (or resolved with the human)
43
- - [ ] MIGRATION.md committed
45
+ - [ ] Intended `appId`, inventory evidence, and source commit recorded in the
46
+ checkpoint handoff
44
47
 
45
48
  Rollback: nothing to roll back.
46
49
 
@@ -34,7 +34,9 @@ in this session).
34
34
  7. Add non-`deploy` npm scripts so CI never auto-deploys:
35
35
  `"deploy:app:dev": "<build> && wrangler deploy --env dev"` (and later
36
36
  `"deploy:app"` for prod). Never name a script exactly `deploy`.
37
- 8. Record the workers.dev URL and parity results in MIGRATION.md.
37
+ 8. Record the workers.dev URL, immutable deployment version, and parity
38
+ evidence in the focused Phase 1 commit/checkpoint. Backfill that evidence
39
+ into PM immediately after Phase 2 registers the app.
38
40
 
39
41
  ## Verification checklist
40
42
 
@@ -77,6 +77,12 @@ These bite silently; no smoke test catches them.
77
77
  `crm_record` mirrors identity, stage, billing, and Clerk linkage. Leader →
78
78
  follower delivery intentionally copies allowlisted record fields only, not
79
79
  another site's pipeline/account/billing authority.
80
+ - **Leader/follower identity and credentials.** Each website has its own
81
+ `appId`, ODLA tenant/key, Clerk application/issuer, roles, and users. A leader
82
+ browser JWT authenticates only to the leader admin route. The leader Worker
83
+ sends a per-edge vault share secret; the follower validates it and writes
84
+ through its own `ODLA_API_KEY`. Never share a Clerk application between
85
+ websites, accept another site's JWT, or move either ODLA key across the edge.
80
86
  - **Route contracts.** Chapter owns `/api/config` and the group-scoped
81
87
  `/api/join-config`, but a matching path or matching monetary values do not
82
88
  make it a drop-in replacement. Compare method, auth, request body, response
@@ -91,6 +97,12 @@ These bite silently; no smoke test catches them.
91
97
  CRM does not declare that type and fields. Add the type to the follower config
92
98
  and expose it through the standard console before enabling the target in the
93
99
  leader.
100
+ - **People workspace width.** The standard CRM list uses the full workspace
101
+ width until a record is selected, then becomes master/detail. Keep
102
+ `collectionSection({ collapseClosedDetail: true })` unless the empty detail
103
+ pane contains intentional useful content. `renderMaster` and `renderSummary`
104
+ customize content, not pane geometry. At 1280/1440 prove a wide table is not
105
+ squeezed into a narrow rail beside an empty pane.
94
106
 
95
107
  ## Install notes
96
108
 
@@ -11,8 +11,11 @@ opens the review page in interactive terminals; loading it alone is inert.
11
11
 
12
12
  ## Steps
13
13
 
14
- 1. Require `npm view @odla-ai/cli@0.16.6 version` to succeed, then run
15
- `npm i -D --save-exact @odla-ai/cli@0.16.6` and `npm i @odla-ai/db`.
14
+ 1. Require `npm view @odla-ai/cli version` to succeed, then run
15
+ `npm i -D @odla-ai/cli` and `npm i @odla-ai/db`. Use normal dependency
16
+ declarations while ODLA is under active development, commit the lockfile,
17
+ and record the resolved graph from
18
+ `npm ls @odla-ai/cli @odla-ai/db` in PM.
16
19
  2. `npx @odla-ai/cli init --app-id <id> --name "<Name>" --env dev --services db`
17
20
  Review `odla.config.mjs`. Keep `envs: ["dev"]` — prod is Phase 5. Set
18
21
  `links.dev` to the URL the Phase 1 `wrangler deploy` **actually printed** —
@@ -50,6 +53,10 @@ opens the review page in interactive terminals; loading it alone is inert.
50
53
  init — confirm with `git status`. Use
51
54
  `npx @odla-ai/cli secrets push --env dev` only to retry the secret-transfer
52
55
  portion (details and manual fallback: references/secrets-map.md).
56
+ 8. The app now exists. Before further implementation, follow
57
+ `project-state.md`: create the migration goals/tasks/decisions in PM,
58
+ backfill the approved Phase 0/1 evidence, and read the resulting active
59
+ task/goal before continuing.
53
60
  9. Add to `wrangler.jsonc` `env.dev.vars`: `ODLA_ENDPOINT`
54
61
  ("https://db.odla.ai"), `ODLA_TENANT` ("<appId>--dev"),
55
62
  `ODLA_PLATFORM` ("https://odla.ai"), `ODLA_APP_ID`, `ODLA_ENV`
@@ -70,7 +77,8 @@ opens the review page in interactive terminals; loading it alone is inert.
70
77
  - [ ] Routes work locally and on the deployed dev worker
71
78
  - [ ] `links.dev` set — public-config carries the URL and Studio shows it
72
79
  - [ ] `git status` shows no credential files staged
73
- - [ ] MIGRATION.md updated with tenant id + route list
80
+ - [ ] PM initialized and Phase 0/1 evidence backfilled; Phase 2 route/tenant
81
+ evidence attached to the active task without credentials
74
82
 
75
83
  Rollback: the dev tenant is disposable; the live site never depended on
76
84
  it. Pages untouched.
@@ -16,10 +16,10 @@ routes are **server-side only** — they authenticate with the app's full
16
16
  this app's own Worker endpoints and may import pure helpers from
17
17
  `@odla-ai/calendar/client`.
18
18
 
19
- 1. Require `npm view @odla-ai/calendar@0.2.0 version` to succeed, then
20
- install `npm i --save-exact @odla-ai/calendar@0.2.0` as a runtime
21
- dependency. An exact-version `E404` blocks this phase; do not substitute a
22
- git checkout or another version.
19
+ 1. Require `npm view @odla-ai/calendar version` to succeed, then install
20
+ `npm i @odla-ai/calendar` as a runtime dependency. Use the normal dependency
21
+ range, commit the lockfile, and record `npm ls @odla-ai/calendar` in PM. A
22
+ registry failure blocks this phase; do not substitute a git checkout.
23
23
  2. Add `"calendar"` beside `"db"` in services and author the config block —
24
24
  booking rides the existing db key, so calendar adds no new secret:
25
25
 
@@ -127,4 +127,5 @@ same idempotency key returns `duplicate: true` (no second event); a taken
127
127
  slot returns 409 and the UI refetches slots; reschedule and cancel work via
128
128
  the stored `eventId`; zero attendee data is persisted anywhere except the
129
129
  app's own tenant record; no Google credential exists in local files; and
130
- `MIGRATION.md` records the booking-flow decision.
130
+ PM records the booking-flow decision and the active task comment links this
131
+ evidence.
@@ -22,6 +22,12 @@ doc — `https://clerk.com/docs/cli.md` — and prefer its syntax over the liter
22
22
  flags below. The steps here are the odla-shaped sequence; the live doc is
23
23
  authoritative for commands and flags.
24
24
 
25
+ The development and production instances below belong to this one website's
26
+ Clerk application. A separate leader or follower website uses its own Clerk
27
+ application, issuer, publishable keys, roles, and users. Cross-site Chapter
28
+ record delivery uses a per-edge vault share secret and the follower's own ODLA
29
+ key; it never forwards or accepts another site's Clerk JWT.
30
+
25
31
  ## Steps
26
32
 
27
33
  1. Provision the Clerk app with the CLI (after the human's `clerk auth
@@ -67,6 +73,13 @@ authoritative for commands and flags.
67
73
  and attach `Clerk.session.getToken()` as the `Bearer` on `/api/*` calls.
68
74
  6. Deploy dev (`npm run deploy:app:dev`).
69
75
 
76
+ Record and test the complete auth matrix: signed out, allowed, forbidden,
77
+ malformed, expired, wrong issuer, role ladder, and sign-out/return routing. If
78
+ the legacy verifier intentionally enforced `aud` or `azp`, preserve it with a
79
+ host verifier and add negative fixtures until the replacement has the same
80
+ policy. If it never enforced them, record those two cases as `n/a`; that is
81
+ inherited policy scope, not proof that the rest of authorization is correct.
82
+
70
83
  Clerk is the **source of truth** for identity; odla-db keeps a mirror in
71
84
  `$users`. Shipping login (this phase) is enough to gate routes. Mirroring
72
85
  users into `$users` (svix webhook, "full" mode) is a **separate, optional
@@ -138,7 +151,8 @@ works. Before writing any markup:
138
151
  palette, logo, spacing) — human-confirmed, not self-asserted
139
152
  - [ ] Post-login redirect lands on a real URL (mind trailing-slash /
140
153
  directory-index routing), not a 404
141
- - [ ] MIGRATION.md updated (gated routes, Clerk instance name)
154
+ - [ ] PM records the gated routes, this site's Clerk app/instance decision,
155
+ source commit, and deployed verification evidence
142
156
 
143
157
  Rollback: remove the auth layer / ungate the route; nothing outside dev
144
158
  changed.
@@ -36,7 +36,8 @@ own terminal so you never see the value.
36
36
  - [ ] The AI route returns a model response on the deployed dev worker
37
37
  - [ ] `wrangler.jsonc` `vars` contain NO provider key; `git grep` for the
38
38
  key's prefix finds nothing
39
- - [ ] MIGRATION.md updated (provider, model, route)
39
+ - [ ] PM records the non-secret provider/model/route decision and deployed
40
+ verification evidence
40
41
 
41
42
  Rollback: remove the route; the vault key can be rotated/removed in
42
43
  Studio.
@@ -24,10 +24,10 @@ instance, never a second Clerk app per env; final go/no-go at each step.
24
24
  `secrets push --env prod --yes` only to retry the transfer (see
25
25
  references/secrets-map.md).
26
26
  3. Build, then run the passive pre-cutover security gate:
27
- first require `npm view @odla-ai/security@0.3.1 version` to succeed. An
28
- exact-version `E404` means the release is unavailable and blocks cutover;
29
- it is not a clean scan and does not prove the package name is absent. Run
30
- `npm i -D --save-exact @odla-ai/security@0.3.1` followed by
27
+ first require `npm view @odla-ai/security version` to succeed. A registry
28
+ failure blocks cutover; it is not a clean scan. Run
29
+ `npm i -D @odla-ai/security`, commit the lockfile, record the resolved
30
+ version from `npm ls @odla-ai/security`, then run
31
31
  `npx odla-security scan . --profile odla --out .odla/security/pre-cutover --fail-on high --fail-on-candidates critical`.
32
32
  Review `REPORT.md`; a candidate is a lead, not confirmation, and a baseline
33
33
  requires a concrete reason, owner, and expiry.
@@ -56,8 +56,9 @@ instance, never a second Clerk app per env; final go/no-go at each step.
56
56
  in and out), `/api/*` routes, the AI route if present. Use a unique
57
57
  non-secret query value and capture cache/version headers so an earlier
58
58
  edge-cached response cannot masquerade as the deployed build.
59
- 9. Update MIGRATION.md: cutover timestamp, verification results, and a
60
- dated reminder 72 hours out to decommission Pages.
59
+ 9. Comment on the PM cutover task with the timestamp, immutable deployment
60
+ version, verification results, rollback checkpoint, and a dated follow-up
61
+ task ≥ 72 hours out to decommission Pages.
61
62
  10. After ≥ 72 hours of clean parallel-run and explicit human
62
63
  confirmation: disable GitHub Pages in the repo settings. KEEP the
63
64
  repo — it is still the source of the site.
@@ -90,6 +91,7 @@ production on the *existing* app. Then:
90
91
  Rollback: point DNS back at GitHub Pages (minutes). Nothing on the
91
92
  odla/Cloudflare side needs to be torn down to roll back.
92
93
 
93
- Done when: the 72-hour confirmation is done and MIGRATION.md is closed
94
- out. Congratulate the human and mention Studio (https://odla.ai/studio) as
95
- where they watch their app from now on.
94
+ Done when: the 72-hour confirmation is done, every migration conformance goal
95
+ is met, and the remaining PM tasks are completed or explicitly deferred.
96
+ Congratulate the human and mention Studio (https://odla.ai/studio) as where
97
+ they watch their app and PM state from now on.
@@ -0,0 +1,80 @@
1
+ # Project state — use PM, not a migration diary
2
+
3
+ The migration's durable coordination state lives in odla PM. Do not create or
4
+ maintain a parallel migration/status diary in the source tree. Source files
5
+ describe the product; PM describes goals, active work,
6
+ decisions, defects, and verification evidence across agents and sessions.
7
+
8
+ ## Bootstrap before the odla app exists
9
+
10
+ PM items require a registered, co-owned app. Phase 0 and Phase 1 deliberately
11
+ precede platform registration, so do not pretend PM is available yet and do not
12
+ borrow an unrelated app as a container.
13
+
14
+ 1. Choose the intended stable `appId` during Phase 0.
15
+ 2. Keep each early phase in a focused branch/commit. Put the phase, immutable
16
+ source commit, evidence locations, and next gate in the checkpoint handoff
17
+ and commit message. Do not create a diary file.
18
+ 3. A fresh agent before registration reruns the Phase 0 inventory checks, reads
19
+ the focused commits, and treats old branches, git history, unrelated
20
+ deployments, and prior experiments only as leads to verify.
21
+ 4. Immediately after the first successful Phase 2 `provision` registers the
22
+ app, initialize PM and backfill the approved Phase 0/1 outcomes and evidence.
23
+ From then on, PM is authoritative.
24
+
25
+ This bootstrap gap ends at registration. Do not keep using commit messages as
26
+ project management after PM becomes available.
27
+
28
+ ## Initialize the migration in PM
29
+
30
+ Read the complete PM command contract at
31
+ `../../odla/references/pm.md`. Never put a credential or secret in an item or
32
+ comment.
33
+
34
+ Create:
35
+
36
+ - one conformance goal per acceptance outcome, with a concrete proof path or
37
+ command;
38
+ - one task per migration track or phase, linked to its goal and placed in the
39
+ correct board column;
40
+ - a decision for each product, data-authority, identity, route-contract, or
41
+ rollback choice;
42
+ - a bug for every observed defect, including defects outside the current task.
43
+
44
+ Backfill Phase 0/1 as completed tasks with comments naming the reviewed source
45
+ commit, immutable deployment version where applicable, evidence artifact, and
46
+ human checkpoint. Do not copy secrets or large logs into PM.
47
+
48
+ ## Start every later session by reading
49
+
50
+ Resolve `appId` from `odla.config.mjs`; do not guess it from a repository name,
51
+ deployment, old branch, or conversation.
52
+
53
+ ```cmd
54
+ npx @odla-ai/cli pm task list --app <appId> --column doing
55
+ npx @odla-ai/cli pm bug list --app <appId> --status open
56
+ npx @odla-ai/cli pm decision list --app <appId> --limit 20
57
+ npx @odla-ai/cli pm goal list --app <appId> --status open
58
+ ```
59
+
60
+ Read the linked goal and the active task's comments before editing. Confirm
61
+ their source commit/deployment evidence still identifies the implementation
62
+ being tested. If PM and the working tree disagree, stop, investigate, and
63
+ record the resolution as a decision or comment; do not silently pick whichever
64
+ is more convenient.
65
+
66
+ ## Update at every gate
67
+
68
+ - Move the phase/track task when work starts.
69
+ - Comment with the exact verification command, result, source commit, candidate
70
+ deployment version, and rollback checkpoint.
71
+ - Record an intentional contract or product delta as a decision.
72
+ - File a defect as a bug rather than hiding it in a task comment.
73
+ - Mark a goal met only after its stated proof passes.
74
+ - Mark a task done only after its goal/evidence and human checkpoint are
75
+ complete.
76
+
77
+ For parallel migrations, keep separate tasks per track (runtime, data, auth,
78
+ payments, scheduling, email, public UI, admin UI, observability) and link each
79
+ to its own conformance goal. This lets multiple agents claim independent work
80
+ without sharing a branch or overwriting one status document.