Skip to content

Anthropic built Scion for itself. Carbon Forge is yours →

Carbon Forge
Menu

Guida

Integrare una modifica al codice e la sua documentazione in un solo changeset

Una modifica al codice e la pagina che la documenta vengono integrate nello stesso changeset, insieme o per niente. Questa guida segue una di queste modifiche da una lane aperta a una sola integrazione.

Anche in: English, Español, Português, 日本語, Deutsch, Français, 한국어, 简体中文, हिन्दी · Tutte le guide in italiano

Trasparenza: Carbon Forge è sviluppato da 100monkeys.ai, quindi leggete questa guida come il resoconto di chi lo costruisce. L'ha scritta in bozza uno dei nostri agenti di IA a partire dalla documentazione pubblica, soprattutto Working in lanes e Code and files on the substrate, e l'azienda l'ha rivista; questa edizione italiana è una traduzione della guida originale in inglese. Ogni chiamata qui sotto è l'esempio della documentazione stessa, e le citazioni sono in inglese con la traduzione accanto. Dove la documentazione lascia aperta una domanda, l'ultima sezione lo dice.

Perché un solo changeset

La home della documentazione definisce l'unità: "A changeset is many writes landed as one: every page, atom, code tree and library entry it names is written in one transaction under one intent, the changeset's intent, or nothing is written" (Welcome to Carbon). (Un changeset è molte scritture integrate come una: ogni pagina, atomo, albero di codice e voce di libreria che nomina viene scritto in una sola transazione sotto un solo intento, l'intento del changeset, oppure non viene scritto nulla.) Codice e prosa sono entità di un unico registro, quindi chi legge non trova mai il codice nuovo accanto alla pagina vecchia, e un revert li riporta indietro insieme.

Vi serve un token che possa scrivere lane e alberi; il preset SCM agent è quello che la documentazione indica per questo lavoro.

Passo 1. Scoprite se il trunk è protetto

workspaces.get_settings {}
→ { "workspaceId": "…", "trunkProtected": true, "trunkProtectedEntities": false }

"With trunkProtected, code trees, library entries and changesets go through a lane; with trunkProtectedEntities as well, page and atom edits do too." (Con trunkProtected, alberi di codice, voci di libreria e changeset passano per una lane; con anche trunkProtectedEntities, anche le modifiche a pagine e atomi.) In ogni caso una lane è la forma giusta qui: la documentazione la usa quando "a change should be seen whole before it lands." (una modifica va vista per intero prima di essere integrata.)

Passo 2. Aprite una lane per la modifica

lanes.create { "label": "agent/7/fix-login" }

Un'etichetta è fatta di segmenti minuscoli separati da barre, unica tra le lane aperte. "A lane costs nothing to open and holds no copy, so one per task, or one per agent, is the expected use." (Aprire una lane non costa nulla e non contiene copie, quindi una per compito, o una per agente, è l'uso previsto.) Passate owner perché solo voi possiate scrivere, risolvere e integrare la lane.

Passo 3. Modificate il codice sulla lane

trees.apply_patch { "path": "app", "operations": [ { "op": "patch", "entry_path": "src/login.ts", "old_string": "password", "new_string": "magicLink" } ], "intent": "fix: accept magic links", "lane": "agent/7/fix-login" }

Passate l'etichetta come lane e "the write is held on the lane as a patch against the trunk" (la scrittura resta sulla lane come patch rispetto al trunk): "the trunk is not written." (il trunk non viene scritto.) trees.apply_patch invia solo le sue operazioni (una sostituzione dentro un file, una scrittura, una rimozione o uno spostamento); trees.put invia l'intero elenco di voci dell'albero. In entrambi i casi "the lane keeps only what differs." (la lane conserva solo ciò che differisce.)

Passo 4. Modificate la pagina che lo documenta, sulla stessa lane

pages.apply_patch { "pathOrId": "guides/login", "old_string": "Sign in with a password.", "new_string": "Sign in with a magic link.", "lane": "agent/7/fix-login" }

Stessa etichetta, così la modifica della pagina aspetta accanto al codice. Se la modifica rinomina anche una pagina, pages.move accetta anch'esso lane, e "a rename belongs to the change that needs it." (una rinomina appartiene alla modifica che ne ha bisogno.) Uno screenshot entra allo stesso modo con library.put_at_path e l'etichetta.

Passo 5. Leggete cosa produrrebbe la lane

Passate la stessa lane a una lettura e "the answer is the trunk as it stands now with the lane's patches applied, composed on the call" (la risposta è il trunk com'è ora con le patch della lane applicate, composto al momento della chiamata): pages.read per la pagina, trees.get, trees.diff o trees.grep per il codice. Poi rivedete l'insieme:

lanes.diff { "label": "agent/7/fix-login" }
lanes.get { "label": "agent/7/fix-login" }

lanes.diff risponde "entity by entity, the trunk's section and the lane's" (entità per entità, la sezione del trunk e quella della lane); lanes.get risponde con le patch, i conflitti e landable: "open, at least one live patch, no conflict." (aperta, almeno una patch viva, nessun conflitto.) Nell'app, /<workspace>/lanes/<label> mostra lo stesso, con ogni file di testo modificato come diff unificato. Un revisore che legge lanes.export e approva al suo hash di composizione "has approved exactly that change." (ha approvato esattamente quella modifica.)

Passo 6. Risolvete eventuali conflitti

Se nel frattempo qualcuno ha modificato sul trunk le stesse righe della pagina o del file, la patch è in conflitto, e "nothing merges by itself." (nulla si fonde da solo.) lanes.conflicts dà la patch, la sezione com'era, la sezione del trunk ora e i changeset che l'hanno spostata. Rispondete con lanes.resolve o scartate la patch con lanes.drop_patch. Una sostituzione dentro un file "replays on the trunk's current file, so two agents changing different parts of one file both land." (si riapplica al file attuale del trunk, quindi due agenti che modificano parti diverse dello stesso file vengono integrati entrambi.)

Passo 7. Integrate una volta sola, con un intento

lanes.land { "label": "agent/7/fix-login", "intent": "fix: accept magic links", "dry_run": true }
lanes.land { "label": "agent/7/fix-login", "intent": "fix: accept magic links" }

Eseguite prima la prova a secco, poi l'integrazione. "Every live patch is replayed as one changeset whose intent is lane agent/7/fix-login: fix: accept magic links" (Ogni patch viva viene riapplicata come un solo changeset con quell'intento), ricontrollata dentro la propria transazione e "refused whole, with every conflict named, if anything moved." (rifiutata per intero, con ogni conflitto nominato, se qualcosa si è mosso.) Iniziate l'intento con feat, fix, docs, chore o revert e le note di rilascio lo raggruppano sotto quella parola. Inviate una idempotency_key e un nuovo tentativo dopo un timeout "answers the first landing's result instead of landing twice." (risponde con il risultato della prima integrazione invece di integrare due volte.)

Passo 8. Rileggete l'integrazione

Aprite /<workspace>/changes/<id>: mostra l'intento completo, l'attore, la lane da cui è stato integrato, il suo sigillo e le sue voci, il file di codice e la pagina insieme. Il blame sulla riga modificata ora risponde con l'intento che avete scritto: trees.blame dà "each line's revision, changeset, intent, actor and landing lane" (per ogni riga revisione, changeset, intento, attore e lane di integrazione) (Code and files). Per annullare entrambi insieme, changesets.revert scrive un nuovo changeset che ripristina ogni entità scritta dall'integrazione.

Cosa la documentazione lascia senza risposta

Guide correlate

Integrate il codice e la sua documentazione insieme.