Every claim in this handbook carries a tag, so you can tell documentation from observation from opinion.
- DDocumented. Documented by Microsoft on Learn, Support, Message center, GitHub or an official blog, as of the dates in Appendix E
- OObserved. Observed first-hand on 7 November 2026 in a live Copilot Code cloud session: its tools, its sandbox, an example tenant's policy verdicts, and the repository of a production partner-sales app
- CCommunity. Reported by the community (MVP blogs, forums, videos, GitHub issues) and not confirmed by Microsoft
- IInference. Inference or recommendation by the author; test it before you rely on it
Part 17
Which tool for which job: a workflow by phase
- What it isA ten-phase workflow showing which tool leads each phase of an app's life, four patterns that work, and rules for switching tools.
- What you doKeep the repository as the source of truth, leave a handoff note, and start every session with the same prompt.
- Watch outHand-offs between tools are where work gets lost, so never let two sessions release at the same time.
Decide this in the setup Step 1: Start
The fastest way to waste a week is to do every phase in whichever tab happened to be open. Each phase has a natural home, and the hand-offs between them are where apps get lost.
| Phase | Lead tool | Support | What good looks like | Example prompt |
|---|---|---|---|---|
| 1. Discover | Cowork | Code for research | Problem, users, data sources and current process written down | "Find every spreadsheet, list and email thread about partner deal registration from the last 90 days. Summarize the process, the owners and the pain points." |
| 2. Specify | Code in Plan mode | Cowork to review with stakeholders | A numbered, testable spec in the repository | "Plan only. Write DESIGN.md: numbered items a person can see or click, the data contract, navigation, out of scope. Wait for my approval." |
| 3. Model the data | Cowork or Copilot Studio | Code to bind and verify | System of record chosen, lists or tables created, sample rows in place | "Create the Partner Registrations list on the Sales site with these columns." Then in Code: "Bind it in table mode and show me the generated fields." |
| 4. First build | Cowork App skill or Code | None | One end-to-end path working on real data | "/app Build the registration tracker from DESIGN.md items 1 to 5 only." |
| 5. Engineer | Code | None | Small changes, tests added, checks green | "Implement DESIGN.md item 6. Touch only what it needs. Add or update tests." |
| 6. Verify | Code (scripted) and Cowork (live) | A person with a checklist | Evidence for every spec item at desktop and phone width | Code: "Run the release checks and screenshots." Cowork: "Open the play link and walk this checklist." |
| 7. Release | Code | None | Rubric at or above the bar, a named commit deployed, the release logged | "Run the release: checks, score, rebase, publish, confirm live, log it." |
| 8. Share and announce | Cowork | None | Shared with a group, release note sent, training material ready | "Share the app with the Partner Sales group, play only, and draft the release note for Teams." |
| 9. Operate | Cowork scheduled tasks and the admin center | Code for fixes | Weekly health check, feedback triaged, connections current | "Every Monday at 8:00, open the app, compare totals with the list, read the feedback list and send me a summary." |
| 10. Extend | Copilot Studio | Code | An agent or flow designed where it lives, then bound and tested | "Design an approval flow with a Power Apps trigger. I'll bind it from Code." |
Ten phases, and the tool that leads each one
- 1DiscoverCowork
- 2SpecifyCode in Plan mode
- 3Model the dataCowork or Copilot Studio
- 4First buildCowork App skill or Code
- 5EngineerCode
- 6VerifyCode (scripted) and Cowork (live)
- 7ReleaseCode
- 8Share and announceCowork
- 9OperateCowork scheduled tasks and the admin center
- 10ExtendCopilot Studio
Cowork leadsCode leadsMore than one toolCopilot Studio leads
What good looks like and an example prompt for each phase: open the full table above the chart.
Show the data
| Phase | Lead tool | Support |
|---|---|---|
| 1. Discover | Cowork | Code for research |
| 2. Specify | Code in Plan mode | Cowork to review with stakeholders |
| 3. Model the data | Cowork or Copilot Studio | Code to bind and verify |
| 4. First build | Cowork App skill or Code | None |
| 5. Engineer | Code | None |
| 6. Verify | Code (scripted) and Cowork (live) | A person with a checklist |
| 7. Release | Code | None |
| 8. Share and announce | Cowork | None |
| 9. Operate | Cowork scheduled tasks and the admin center | Code for fixes |
| 10. Extend | Copilot Studio | Code |
17.1Four patterns that work
Cowork shapes, Code ships. Use Cowork to find the data, the people and the process, and even for the first build. Move to Code once the app has more than a few screens, logic that must be right, or more than one person changing it. I
Code builds, Cowork accepts. Code makes each change and runs the scripted checks; Cowork, in Edge, opens the live app as a real user with real data and walks the acceptance checklist; a person signs off. This closes the gap that Code's missing browser leaves. I
Studio for the agent, Code for the app. Agents and flows are designed and governed where they live, in Copilot Studio; the app binds to them and tests the contract. I
The CLI for the pipeline. When an app needs CI/CD, pinned tool versions, GitHub Actions deployment with a service principal or a third-party build tool, move that part to the ms CLI. D
17.2Rules for switching surfaces
- The repository is the source of truth; chats are not. Before you switch tools, make sure the last session committed and pushed.
- Leave a handoff note in the repository: what changed, what was verified, what is next.
- Start every session the same way, with the session-start prompt below.
- Give each session one scope, and name it in the first message.
- Never let two sessions release at the same time.
Fetch the app and compare with the remote main. Read DESIGN.md, QUALITY-RUBRIC.md, RELEASE-LOG.md and HANDOFF.md. Tell me what is live, what is committed but not released, what is in progress in other sessions, and the next step. Don't change anything yet.
Part 18
Day zero: setting up an app properly
- What it isThe decisions, files and kickoff prompt that set up an app properly before the first build prompt.
- What you doSpend about an hour on the fourteen decisions, create the day-zero files, and run the kickoff prompt in plan mode.
- Watch outNo co-owner model or ownership transfer is documented yet, so name a backup owner with edit access from day one.
Decide this in the setup Step 2: The app
Most people just start chatting, and for a demo that is fine. It stops being fine at the second user, the first data question or the first time someone else edits the app. The decisions below take about an hour before the first build prompt, and they are what separates an app that runs for a year from one that is quietly rebuilt in a month.
18.1Fourteen decisions before the first prompt
| Decision | Why it matters | Where it lives |
|---|---|---|
| 1. Problem, users and one measure of success | Keeps scope honest and gives every release a test | DESIGN.md |
| 2. Owner, backup owner and support contact | No co-owner model or ownership transfer is documented yet; edit sharing is how a backup gets access | README.md |
| 3. Where the app will live | Apps start in the maker's personal developer environment; plan the path before a team depends on it | DECISIONS.md |
| 4. System of record for each kind of data | Decides security, scale and who can fix bad data | DESIGN.md, data contract |
| 5. Identity model | Per-user connections by default; shared connections need declared actions and give no row-level security | DESIGN.md |
| 6. Connector check | Default allow-list, DLP verdicts, blocked actions, Premium connectors | DECISIONS.md |
| 7. Read-only boundaries | Systems the app must never write to, enforced in code and tests | DESIGN.md and saved memory |
| 8. Sample-data inventory | Which screens may run on sample data, and until when | DESIGN.md |
| 9. Quality bar | A rubric with hard gates and a release threshold | QUALITY-RUBRIC.md |
| 10. Release policy | Who can say "publish", what evidence is required, how to roll back | QUALITY-RUBRIC.md |
| 11. Feature switches | Unfinished work ships dark | src/features.ts |
| 12. Navigation rules | Every screen names itself and has a one-click, labelled "Back to ..."; no silent redirects | DESIGN.md |
| 13. House style | Spelling, words to avoid, visual rules | QUALITY-RUBRIC.md |
| 14. Lifecycle and cost | Review date, retirement plan, who pays the runtime credits | README.md |
18.2Choosing the system of record
| If you need | Use | Avoid |
|---|---|---|
| Shared records with relationships, roles and row-level security | Dataverse, added to the environment first | SharePoint lookups as a relational database |
| Simple team lists with attachments and existing SharePoint permissions | A SharePoint list | Excel as a multi-user database |
| Per-user settings, drafts and saved items | A JSON file in each user's OneDrive, through the connector, with a local cache | Browser storage as the only copy |
| Team-shared configuration such as allowed domains, thresholds and pilot rings | A small SharePoint list the owner controls | Hard-coded values that need a release to change |
| Read-only analytics | A Power BI semantic model or Fabric | Recomputing large aggregates in the browser |
| One-off imports | File upload parsed in the browser; the template already includes an Excel library | Pasting data into the chat every time |
| An existing line-of-business system | Its connector, read-only first, with an admin exception if needed | Copying its data into lists by hand |
18.3Files to create on day zero
| File | Purpose |
|---|---|
| README.md | What the app is, who it is for, play link, owner and backup, support, status, next review date |
| DESIGN.md | Numbered spec items a person can see or click; data contract; navigation; sample-data inventory; out of scope |
| DECISIONS.md | Dated decisions with the reason and the alternative rejected |
| QUALITY-RUBRIC.md | Release run, machine checks, hard gates, scored items, house style, known issues, scorecard log |
| RELEASE-LOG.md | One entry per release: commit, score, evidence, what is still owed, rollback point |
| HANDOFF.md | Where the last session stopped: live, committed but unreleased, next step, watch-outs |
| src/features.ts | Feature switches, all off by default, each with an owner and a removal date |
| qa-tests/ | Unit and component tests, fixtures, a screen check and a release scan |
The template already contains an AGENTS.md written by the platform for any coding agent, and its own README says it is deliberately not the whole contract: the app service's own rules sit outside the repository. O Keep your project rules in your own files and tell every session to read them. Files are the only memory you fully control. I
18.4A kickoff prompt that sets all of this up
Plan only; don't build yet. We are creating [app name] for [users] so they can [outcome], and we will know it works when [measure]. Data: [system of record with exact site, list or table names]. These sources are read-only and must never be written to: [list]. Create README.md, DESIGN.md (numbered, testable items; data contract; navigation rules: every screen names itself and has a one-click Back link; out of scope), DECISIONS.md, QUALITY-RUBRIC.md (release only at 90 of 100 with hard gates), RELEASE-LOG.md, HANDOFF.md and src/features.ts. List which screens will run on sample data and why. Ask me what you need as multiple-choice questions, then show me the plan.
Part 19
Building: prompting patterns that hold up
- What it isPrompting patterns that counter coding agents' habits of doing the minimum, forgetting context and grading their own work generously.
- What you doWrite spec items a person can see or click, make one change at a time, and ask for evidence rather than adjectives.
- Watch outAgents can quietly build on sample or mock data, so make every build summary list anything not using live data.
Coding agents optimize for work that looks done. They build the smallest thing that satisfies a request, forget context between sessions and grade their own work generously. Every pattern below exists to counter one of those three habits. C
19.1Patterns
Re-check after Ignite
- Write spec items a person can see or click. "Help has a Search box that filters topics as you type" is a spec item; "better Help" is not. O
- Make one change at a time and say what must not be touched. Microsoft's own guidance for Code is one focused change per request. D
- Settle the data contract before the screens: the list, the fields, their types, some sample rows, and what each screen does when the data is empty, slow or failing. Unless asked, agents skip empty, loading and error states. C
- Name every list and table exactly, with the site URL, list name or Dataverse logical name. Builders report apps that looked finished but saved nothing until the list was named in the prompt. C
- Point instead of describing: select the element on the Code canvas, or attach a screenshot of what you want. D
- State the navigation rules up front: every screen names itself, carries a labelled "Back to <origin>", sibling modes share one switch on both screens, and nothing redirects silently. O
- Ask for evidence, not adjectives: "show me the command and its output" or "show me the screenshot". A summary that claims something no tool output shows should fail the release. O
- Use models deliberately: the strongest reasoning model for planning, reviews and logic that must be right; a faster model for copy edits and small fixes. I
- Build in passes. Ask the agent to say what it added and what it deferred, test that, then say "Continue". C
- Keep the spec alive: change DESIGN.md first, then the code.
- Hand over a spec pack, not a paragraph. One builder attached the spec, an entity-relationship diagram and a screenshot of every existing screen, raised effort to High ("slower, but more thorough") and got a seven-table, five-screen app in under an hour; he noted a vague prompt would have cost more. C
- Read the plan like a solution design. Plan mode returned a full information architecture (13 lists, 3 libraries and a build order) in about two minutes for one builder, who moved a risky integration to phase two before approving. Edit the plan; it is the cheapest place to change your mind. C
- Demand live data in every build summary: "Confirm that every screen reads and writes the real source, and list anything still on sample or mock data." Agents have been seen quietly creating local mock data. C
- Paste errors back word for word, with what you were doing: "I'm getting the following error when I try to save: ..." The agent fixes faster from the exact text than from a description. C
- Check the bill as you go. Type /cost after a build in Cowork D; A /cost command is not documented for Code I; builders report that it works there C. Budget per app, not per task, because whole-app builds have cost about 670 to 5,400 credits. C
- Turn off Always allow when you're done. Once on, it stays on for existing and new Code sessions until you switch it off. D
19.2Anti-patterns
- One giant prompt for the whole app. Long, sprawling instructions degrade results; split the work into numbered items. C
- Letting the agent invent data, packages or field names. Check them against the source.
- Accepting "should work". No evidence means zero.
- Hand-editing generated/ or ms.config.json. Use the binding tools so the typed clients stay in step. D
- Releasing two features in one change, which makes both harder to verify and to roll back.
- Publishing from a stale clone.
- A third correction in the same thread. Start a fresh session with a better prompt instead. C
- Treating the builder's self-review as review. Use an independent reviewer that sees only the spec and the change. C
19.3Prompts for common moments
| Moment | Prompt |
|---|---|
| Start of every session | Use the session-start prompt in section 28.2. |
| Before a feature | "Plan DESIGN.md item 7: the files you will touch, the tests you will add, the risks. Don't change anything yet." |
| After a build | "Run the machine checks and show me the output. List anything still running on sample data." |
| Visual check | "Render the changed screens at 1280 and 390 pixels with headless Chromium and show me the screenshots." |
| Review | "Have an independent reviewer score this change against QUALITY-RUBRIC.md, with evidence for each item." |
| Release | "Release: rebase on main, publish, confirm the live app holds the change, and log the scorecard." |
| Rollback | "The last release broke the export. Redeploy commit a1b2c3d and log the rollback." |
| End of session | "Update HANDOFF.md with what is live, what is pending and the single next step." |
Part 20
Quality gates and release management
- What it isA release run, machine checks, hard gates, a 100-point rubric and rollback, generalized from a production app's practice.
- What you doAdopt the rubric, release only at 90 or more with every hard gate passed, and log every score with its evidence.
- Watch outNo evidence means zero, and rolling back code does not roll back data.
Decide this in the setup Step 9: Quality and operations
A production partner-sales app studied for this guide releases against a written rubric, version 2.1, kept in the repository and read at the start of every session that changes the app. Its rule is simple: release only at 90 out of 100 or more, with every hard gate passed; below 90, hold the release and list each missing point with the fix that earns it back. The sections below generalize that rubric so any app can adopt it. O
The 100-point release rubric, and the bar at 90
- Matches the spec 15 points
- Proved it works 15 points
- Visual polish 15 points
- Words 11 points
- Navigation and links 10 points
- Security and safety 15 points
- Data and connections 4 points
- Speed 5 points
- Accessible 5 points
- Clean project 5 points
Hard gates block a release at any score (section 20.3). Below 90, hold the release and list each missing point.
Show the data
| Item | As stated | Unit | Evidence | Part | Source |
|---|---|---|---|---|---|
| A. Matches the spec | | A. Matches the spec | 15 | | points | O | 20 (20.4) | In the part text |
| B. Proved it works | | B. Proved it works | 15 | | points | O | 20 (20.4) | In the part text |
| C. Visual polish | | C. Visual polish | 15 | | points | O | 20 (20.4) | In the part text |
| D. Words | | D. Words | 11 | | points | O | 20 (20.4) | In the part text |
| E. Navigation and links | | E. Navigation and links | 10 | | points | O | 20 (20.4) | In the part text |
| F. Security and safety | | F. Security and safety | 15 | | points | O | 20 (20.4) | In the part text |
| G. Data and connections | | G. Data and connections | 4 | | points | O | 20 (20.4) | In the part text |
| H. Speed | | H. Speed | 5 | | points | O | 20 (20.4) | In the part text |
| I. Accessible | | I. Accessible | 5 | | points | O | 20 (20.4) | In the part text |
| J. Clean project | | J. Clean project | 5 | | points | O | 20 (20.4) | In the part text |
| Release bar | 90 out of 100 | points out of 100 | O | 20 | In the part text |
20.1The release run, in about ten minutes
| Step | What to do | Evidence |
|---|---|---|
| 1. Spec | Write the change as a numbered checklist of things a person can see or click, and name anything left out on purpose | The list, in the chat and in DESIGN.md |
| 2. Build | Make the change, touching only what the spec needs | The diff |
| 3. Machine checks | Run the type check, build and lint; the tests, including a screen check; and the release scan | Command output |
| 4. Preview check | Click every spec item, every changed link and Back, at desktop width and about 390 pixels, then Tab through the changed screen | Screenshots, or the owner's quoted reply to a preview checklist |
| 5. Score | Fill in the scorecard with evidence from this round only | The scorecard |
| 6. Clean up | Remove debug code, dead code, stray files and comments that describe old behavior; rerun the scan | Scan output |
| 7. Release | Commit, pull with rebase, push, deploy the pushed commit; if the push is refused, use the one-call publish | The commit id |
| 8. Confirm live | Fetch and check that the remote main holds the change, open the live link and check one spec item; roll back if it is missing | The live check |
| 9. Log | Add the scorecard to the log, in the release commit | The log entry |
20.2What the machines check
| Check | Covers | Blocks the release on |
|---|---|---|
| bun run check | Type check, production build, lint | Any error |
| bun test qa-tests | Logic tests (scores, totals, send checks, data merges) and a screen check that renders every route of the real app in a headless page | Any failed test |
| bun qa-tests/release-scan.ts | Compares with the last pushed version: links to routes that don't exist, lab pages outside development builds, keys or tokens in code, tokens in browser storage, eval, unsanitized HTML, debugger statements, focused tests, edits to protected template files | Any new error |
The screen check in that app also reports controls without accessible names, screens without exactly one main heading, images without alt text, unlabeled inputs, slow first renders and console errors. It runs in a simulated page with no layout engine, so alignment, overlap, clipping and contrast still need eyes. O
20.3Hard gates
Any one of these blocks a release, whatever the score:
- A type, build, lint or test failure.
- A new error from the release scan.
- Any path that can send or save something outside the app (an email, a record) without passing its checks.
- Customer content, tokens or connector errors written to logs, URLs or analytics.
- A spec item missing without an agreed deferral, or a summary that claims something no tool output shows.
- After release, the live version does not hold the change.
20.4The 100 points
| Area | Points | What earns them |
|---|---|---|
| A. Matches the spec | 15 | Every item done, including empty, loading and error states; each checked off with evidence; no leftover old behavior; nothing unrelated touched |
| B. Proved it works | 15 | Checks pass with no new warnings; tests added when logic changes; every changed flow clicked through; nearby flows still work |
| C. Visual polish | 15 | Shared edges and alignment, theme tokens only, readable type, no decorative filler, checked at desktop and narrow widths |
| D. Words | 11 | Consistent spelling, no marketing filler, labels that say what happens, status messages that tell the truth, Help updated |
| E. Navigation and links | 10 | Every control goes somewhere real; people know where they are and can get back; screens load on refresh; external links open safely |
| F. Security and safety | 15 | Send and save checks on every path; outside content never runs; numbers trace to their source; nothing sensitive in logs, URLs or storage |
| G. Data and connections | 4 | Changed connector calls checked against live data; failures show a clear way forward |
| H. Speed | 5 | No freeze over 200 milliseconds on full-size data; every wait has a label, a timeout or a way out |
| I. Accessible | 5 | Keyboard paths, visible focus, labels and contrast |
| J. Clean project | 5 | No stray files, debug code or dead code |
20.5Scoring rules that keep it honest
- No evidence means zero. Evidence is a command that ran in this round, a test, a measurement or a screen someone looked at.
- Half points when an item was checked in a weaker way than it asks for, such as the screen check instead of the preview.
- Not applicable scores full points only with a one-line reason, and never for something the change touched.
- Record the score even when it fails, with the missing points and how to earn them.
- If the owner overrides the bar, log the override and the evidence still owed. That app did this twice in four days, and both releases are in the log as "preview owed". O
20.6Four ways to see the UI
| Method | Catches | Misses |
|---|---|---|
| Component screen check in a simulated page | Crashes, missing routes, dead links, accessibility basics, console errors | Layout, overlap, contrast |
| Headless Chromium screenshots in the Code sandbox | Layout at 1280 and 390 pixels, overlap and clipping, flows against fixture data | Real data, real sign-in |
| Cowork walk-through in Edge | Real sign-in, real data, real permissions | Exhaustive coverage; needs admin opt-in |
| The owner's preview checklist | Taste, alignment, brand, anything surprising | Whatever is not on the checklist |
20.7Ship dark, then switch on
Unfinished work belongs in the live app behind a switch that is off by default. That app retired an old email composer in seven planned stages, and the first stage went live with every switch off, scoring 91 out of 100. Experimental screens live under a lab route that only development builds include, and the release scan fails if any lab link leaks into a production screen. O Switches can also be read per user from a small SharePoint list, which gives you pilot rings without a release. I
20.8Rollback
The live app serves the deployed build until the next deploy, so rolling back means redeploying a known good commit: ms app deploy with a pinned commit, or asking Code to deploy that commit. Log the failed release and the rollback. Rolling back code does not roll back data, so keep schema and data changes backward compatible for at least one release. DI
Part 21
Many sessions, one app
- What it isRules for running several chat sessions against one app and one repository without losing or undoing work.
- What you doGive each session one scope, allow one releaser at a time, fetch and rebase before every release, and update the handoff note.
- Watch outNothing locks an app, and one builder saw fetch errors at about 1,667 Git objects.
On its busiest day, a production partner-sales app had several chats changing it and releasing to it at once: a header redesign in one, data features in another, an email rework in a third. Twice a session went looking for work it thought had been lost, and both times the work was already live, shipped by another session. The rules below came out of that day. O
21.1Rules
- Start every session with a fetch and a comparison against the remote main. If something seems to be missing, read the log before rebuilding it.
- Give each session one scope and allow one releaser at a time.
- Commit small, with messages that say what changed and why; release small chunks.
- Rebase onto main; never force-push, and never rewrite main's history.
- Leave every session clean: committed and pushed, or explicitly parked, with HANDOFF.md updated.
- Put anything half-built behind a feature switch.
- Record every release in the log, in the release commit itself.
- Watch repository size: the app studied was at about 1,600 Git objects when this guide was written. O
| Situation | What happens | What to do |
|---|---|---|
| Two sessions change different files | The second push is rejected until it rebases; both changes survive | git pull --rebase, rerun the checks, push, deploy the new tip O |
| Two sessions change the same lines | The rebase stops on a conflict | Resolve it in the session that owns that area, then rerun every check I |
| A session deploys from a stale clone | Its deploy can roll the live app back to older code | Always fetch and compare with the remote main before deploying O |
| Work seems to have disappeared | Usually another session already shipped it | Fetch and read the log before rebuilding anything O |
| git push is refused as "disabled" | Some sessions block direct pushes | Use the publish step, which pushes, builds and deploys in one call O |
| Your local commit id differs from the remote tip | The platform adds its own commit on top of each push | After pull --rebase, deploy the remote tip, never your local id O |
| A fetch fails with an I/O or write error in a cloud workspace | The workspace file system, or repository size | Retry with git -c core.logAllRefUpdates=false fetch, and keep an eye on the object count O |
| The latest build failed | A deploy falls back to the last good build, with a warning | Read the build log, fix, and redeploy the commit you meant D |
The table covers each collision and what to do, including a failed fetch.
That is the ceiling one builder hit; plan for it before a release.
21.2Shared files need an owner
Conflicts concentrate in a few shared files: the app header and navigation, the route table, the feature-switch registry, the theme and the rubric itself. Give each one an owner, announce edits to them in the handoff note, and prefer adding a new file over growing a shared one.
21.3Code, Cowork, Studio and the CLI on one repository
All four write to the same repository, and Microsoft documents no lock. Only the CLI documents the clone and pull routine explicitly; agents in Cowork and Copilot Studio push their own commits when you ask them for changes. Treat an edit made in Cowork or Studio exactly like a colleague's commit: before any release from Code, fetch, read what changed, and run the full checks against the combined result. DI