--- title: Documentation Validation | Lightcone description: Northstar validates and self-heals your documentation code examples, catching stale coordinates and API drift before your users do. --- Documentation code examples break silently. A website redesigns, an API method gets renamed, a tutorial’s hardcoded coordinates drift, and your quickstart guide stops working. The first person to discover it is a prospective user who leaves and never comes back. Northstar fixes this by visually locating UI elements and verifying workflows end-to-end, the same way a human QA tester would. ## Self-heal coordinate-dependent examples Tutorials that show GUI interactions with hardcoded coordinates break when the target website or rendering environment changes. Northstar finds the correct coordinates by looking at the screen: heal\_coordinates.py ``` from tzafon import Lightcone client = Lightcone() TOOL = { "type": "computer_use", "display_width": 1280, "display_height": 720, "environment": "browser", } with client.computer.create(kind="browser") as computer: computer.navigate("https://quotes.toscrape.com/login") computer.wait(2) screenshot_url = computer.get_screenshot_url(computer.screenshot()) # Ask Northstar to locate each form element elements = ["username input field", "password input field", "Login button"] for element in elements: response = client.responses.create( model="tzafon.northstar-cua-fast-1.6", tools=[TOOL], input=[{ "role": "user", "content": [ {"type": "input_text", "text": f"Click the {element}"}, {"type": "input_image", "image_url": screenshot_url, "detail": "auto"}, ], }], ) for item in response.output: if item.type == "computer_call": print(f"{element}: ({item.action.x}, {item.action.y})") ``` heal\_coordinates.ts ``` import Lightcone from "@tzafon/lightcone"; const client = new Lightcone(); const tool = { type: "computer_use" as const, display_width: 1280, display_height: 720, environment: "browser", }; const computer = await client.computers.create({ kind: "browser" }); const id = computer.id!; try { await client.computers.navigate(id, { url: "https://quotes.toscrape.com/login" }); await new Promise((r) => setTimeout(r, 2000)); const ss = await client.computers.screenshot(id); const screenshotUrl = ss.result?.screenshot_url as string; const elements = ["username input field", "password input field", "Login button"]; for (const element of elements) { const response = await client.responses.create({ model: "tzafon.northstar-cua-fast-1.6", tools: [tool], input: [{ role: "user", content: [ { type: "input_text", text: `Click the ${element}` }, { type: "input_image", image_url: screenshotUrl, detail: "auto" }, ], }], }); for (const item of response.output ?? []) { if (item.type === "computer_call") { console.log(`${element}: (${item.action.x}, ${item.action.y})`); } } } } finally { await client.computers.delete(id); } ``` Northstar returns exact pixel coordinates for each element. Diff these against the hardcoded values in your docs and update any that have drifted. ## Verify the fix end-to-end After healing coordinates, replay the full workflow to confirm it actually works before committing: verify\_fix.py ``` from tzafon import Lightcone client = Lightcone() # Coordinates from the heal step above coords = { "username": (189, 163), "password": (189, 246), "login": (93, 302), } with client.computer.create(kind="browser") as computer: computer.navigate("https://quotes.toscrape.com/login") computer.wait(2) # Replay the tutorial with corrected coordinates computer.click(*coords["username"]) computer.type("scraper") computer.click(*coords["password"]) computer.type("password") computer.click(*coords["login"]) computer.wait(2) # Verify the workflow actually completes html = computer.get_html_content(computer.html()) assert "Logout" in html, "Login failed; coordinates may still be wrong" print("Verified: tutorial works with healed coordinates") ``` verify\_fix.ts ``` import Lightcone from "@tzafon/lightcone"; const client = new Lightcone(); const coords = { username: [189, 163] as const, password: [189, 246] as const, login: [93, 302] as const, }; const computer = await client.computers.create({ kind: "browser" }); const id = computer.id!; try { await client.computers.navigate(id, { url: "https://quotes.toscrape.com/login" }); await new Promise((r) => setTimeout(r, 2000)); await client.computers.click(id, { x: coords.username[0], y: coords.username[1] }); await client.computers.type(id, { text: "scraper" }); await client.computers.click(id, { x: coords.password[0], y: coords.password[1] }); await client.computers.type(id, { text: "password" }); await client.computers.click(id, { x: coords.login[0], y: coords.login[1] }); await new Promise((r) => setTimeout(r, 2000)); const html = await client.computers.html(id); const content = html.result?.html_content as string; if (!content.includes("Logout")) throw new Error("Login failed"); console.log("Verified: tutorial works with healed coordinates"); } finally { await client.computers.delete(id); } ``` The pattern is: **detect drift** (run examples, catch failures) -> **heal** (ask Northstar for correct coordinates) -> **verify** (replay the full workflow) -> **commit** (update the docs). Run this in CI nightly and broken examples never reach your users. ## Let Northstar run the tutorial itself For the strongest validation, give Northstar the tutorial instructions and let it complete the workflow autonomously. If the agent succeeds, the tutorial works: validate\_tutorial.py ``` from tzafon import Lightcone client = Lightcone() for event in client.agent.tasks.start_stream( instruction=( "Go to https://quotes.toscrape.com/login. " "Log in with username 'scraper' and password 'password'. " "After logging in, verify you can see quotes on the page. " "Report whether the login succeeded and what quotes you see." ), kind="browser", max_steps=15, ): print(event) ``` validate\_tutorial.ts ``` import Lightcone from "@tzafon/lightcone"; const client = new Lightcone(); const stream = await client.agent.tasks.startStream({ instruction: "Go to https://quotes.toscrape.com/login. " + "Log in with username 'scraper' and password 'password'. " + "After logging in, verify you can see quotes on the page. " + "Report whether the login succeeded and what quotes you see.", kind: "browser", max_steps: 15, }); for await (const event of stream) { console.log(event); } ``` This is the highest-fidelity test. Northstar navigates, finds the form fields visually, enters credentials, submits, and verifies the result. No coordinates to maintain at all. ## Why Northstar for docs validation | | Manual QA | Static analysis | Northstar | | ---------------------------- | --------------------------- | ---------------- | -------------------------------------- | | **Catches runtime failures** | Yes, but doesn’t scale | No | Yes, automatically | | **Handles coordinate drift** | Human finds new positions | Cannot | Looks at the screen and finds them | | **Covers real API calls** | Time-consuming | No | Executes against live API | | **Scales with docs growth** | Linearly slower | Fast but shallow | Fast and deep | | **Self-heals** | Requires human intervention | No | Finds correct values and patches files | This pattern is especially powerful for documentation that includes GUI interactions: tutorials showing form filling, web scraping, or multi-step workflows. Traditional static analysis can check syntax but cannot verify that a tutorial actually works when a user follows it. ## See also - [**Software Testing**](/use-cases/software-testing/index.md): test applications with natural language instructions - [**Responses API**](/guides/responses-api/index.md): build custom validation loops with screenshot feedback - [**Computers**](/guides/computers/index.md): manage browser sessions for automated verification