@nac3/forge-cli 1.26.0 → 1.28.0
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/dist/chat/graph_snapshot.d.ts +24 -0
- package/dist/chat/graph_snapshot.d.ts.map +1 -1
- package/dist/chat/graph_snapshot.js +28 -3
- package/dist/chat/graph_snapshot.js.map +1 -1
- package/dist/chat/history_budget.d.ts +114 -0
- package/dist/chat/history_budget.d.ts.map +1 -0
- package/dist/chat/history_budget.js +98 -0
- package/dist/chat/history_budget.js.map +1 -0
- package/dist/chat/panel.d.ts.map +1 -1
- package/dist/chat/panel.js +26 -0
- package/dist/chat/panel.js.map +1 -1
- package/dist/chat/server.d.ts.map +1 -1
- package/dist/chat/server.js +59 -1
- package/dist/chat/server.js.map +1 -1
- package/dist/chat/tools/pending.d.ts.map +1 -1
- package/dist/chat/tools/pending.js +25 -10
- package/dist/chat/tools/pending.js.map +1 -1
- package/dist/chat/tools/pending_ack.d.ts +82 -0
- package/dist/chat/tools/pending_ack.d.ts.map +1 -0
- package/dist/chat/tools/pending_ack.js +55 -0
- package/dist/chat/tools/pending_ack.js.map +1 -0
- package/dist/chat/tools/reader.d.ts.map +1 -1
- package/dist/chat/tools/reader.js +24 -4
- package/dist/chat/tools/reader.js.map +1 -1
- package/dist/commands/operate.d.ts.map +1 -1
- package/dist/commands/operate.js +42 -0
- package/dist/commands/operate.js.map +1 -1
- package/dist/commands/urazuke.d.ts.map +1 -1
- package/dist/commands/urazuke.js +189 -9
- package/dist/commands/urazuke.js.map +1 -1
- package/dist/core/instructions_budget.d.ts +113 -0
- package/dist/core/instructions_budget.d.ts.map +1 -0
- package/dist/core/instructions_budget.js +165 -0
- package/dist/core/instructions_budget.js.map +1 -0
- package/dist/core/limits_config.d.ts +23 -0
- package/dist/core/limits_config.d.ts.map +1 -1
- package/dist/core/limits_config.js +36 -0
- package/dist/core/limits_config.js.map +1 -1
- package/dist/core/machine_files.d.ts +27 -0
- package/dist/core/machine_files.d.ts.map +1 -0
- package/dist/core/machine_files.js +97 -0
- package/dist/core/machine_files.js.map +1 -0
- package/dist/docs/doctrine/session-orchestration.md +109 -109
- package/dist/docs/doctrine/urazuke.md +221 -221
- package/dist/nac3/dispatch_log.d.ts +16 -1
- package/dist/nac3/dispatch_log.d.ts.map +1 -1
- package/dist/nac3/dispatch_log.js +29 -10
- package/dist/nac3/dispatch_log.js.map +1 -1
- package/dist/nac3/manifest_lazy.d.ts +15 -0
- package/dist/nac3/manifest_lazy.d.ts.map +1 -1
- package/dist/nac3/manifest_lazy.js +17 -1
- package/dist/nac3/manifest_lazy.js.map +1 -1
- package/dist/telemetry/battery_events.d.ts +91 -0
- package/dist/telemetry/battery_events.d.ts.map +1 -0
- package/dist/telemetry/battery_events.js +84 -0
- package/dist/telemetry/battery_events.js.map +1 -0
- package/dist/telemetry/usage.d.ts.map +1 -1
- package/dist/telemetry/usage.js +11 -25
- package/dist/telemetry/usage.js.map +1 -1
- package/dist/urazuke/evidence.d.ts.map +1 -1
- package/dist/urazuke/evidence.js +14 -2
- package/dist/urazuke/evidence.js.map +1 -1
- package/dist/urazuke/freeze.d.ts.map +1 -1
- package/dist/urazuke/freeze.js +82 -16
- package/dist/urazuke/freeze.js.map +1 -1
- package/dist/urazuke/gates_data.d.ts +4 -1
- package/dist/urazuke/gates_data.d.ts.map +1 -1
- package/dist/urazuke/gates_data.js +7 -1
- package/dist/urazuke/gates_data.js.map +1 -1
- package/dist/urazuke/gates_ledger.d.ts +25 -1
- package/dist/urazuke/gates_ledger.d.ts.map +1 -1
- package/dist/urazuke/gates_ledger.js +30 -6
- package/dist/urazuke/gates_ledger.js.map +1 -1
- package/dist/urazuke/method_config.d.ts +116 -0
- package/dist/urazuke/method_config.d.ts.map +1 -0
- package/dist/urazuke/method_config.js +328 -0
- package/dist/urazuke/method_config.js.map +1 -0
- package/dist/urazuke/prompts_client.d.ts +42 -12
- package/dist/urazuke/prompts_client.d.ts.map +1 -1
- package/dist/urazuke/prompts_client.js +120 -16
- package/dist/urazuke/prompts_client.js.map +1 -1
- package/dist/urazuke/prompts_freeze.d.ts +186 -0
- package/dist/urazuke/prompts_freeze.d.ts.map +1 -0
- package/dist/urazuke/prompts_freeze.js +498 -0
- package/dist/urazuke/prompts_freeze.js.map +1 -0
- package/dist/urazuke/start.d.ts.map +1 -1
- package/dist/urazuke/start.js +42 -2
- package/dist/urazuke/start.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/docs/doctrine/session-orchestration.md +109 -109
- package/docs/doctrine/urazuke.md +221 -221
- package/package.json +125 -124
package/docs/doctrine/urazuke.md
CHANGED
|
@@ -1,221 +1,221 @@
|
|
|
1
|
-
# Urazuke -- the evidence method, as Forge runs it
|
|
2
|
-
|
|
3
|
-
Urazuke (github.com/pkuschnirof/urazuke) is the method behind every project
|
|
4
|
-
Forge builds or maintains: 24 ordered steps in four stretches, each with an
|
|
5
|
-
exact prompt, the inputs the owner prepares, the artifacts the agent leaves
|
|
6
|
-
in the repository, and a completion check the owner does WITHOUT reading
|
|
7
|
-
code. An existing system built without it goes through eight normalisation
|
|
8
|
-
stations (N0..N7) first and enters the loop at step 5.
|
|
9
|
-
|
|
10
|
-
## What is mechanical (not prose)
|
|
11
|
-
|
|
12
|
-
- The project's workflow is `urazuke` (no code) or `urazuke-legacy` (code
|
|
13
|
-
without the method's artifacts). Every canonical task carries its step.
|
|
14
|
-
- The CURRENT step's prompt is injected into your system prompt every turn,
|
|
15
|
-
with the state of its checks (section "URAZUKE -- peldano NN"). Act on
|
|
16
|
-
that prompt as if the owner had pasted it. Do not skip ahead.
|
|
17
|
-
- A canonical task closes ONLY when `evaluateStep()` is GREEN: the files
|
|
18
|
-
the step names exist, are not stubs, say what they must; the sizing
|
|
19
|
-
record is admissible (G9); the plan items carry a spec; the evidence
|
|
20
|
-
receipts exist. `yujin.pending.close` refuses a red step. An override
|
|
21
|
-
needs the OWNER's written `force_reason` AND its `force_kind` (kept in
|
|
22
|
-
history, counted per motive -- see "A forced close carries a TYPE");
|
|
23
|
-
never pass either on your own initiative.
|
|
24
|
-
- Evidence is a RECEIPT Forge records (command, ref, exit code, counts),
|
|
25
|
-
never your summary. "Tests pass" without a receipt is a claim.
|
|
26
|
-
- A LONG run leaves its receipt the same way. `yujin.evidence.run` blocks
|
|
27
|
-
the turn only while the run fits the blocking window (10 min, lowered with
|
|
28
|
-
`limits.claude_cli_silence_ms`); over that, or with `background: true`, it
|
|
29
|
-
is launched detached and returns a HANDLE. That is not a degraded mode:
|
|
30
|
-
the receipt is written by whoever runs, not by whoever waits. Read it with
|
|
31
|
-
`yujin.evidence.list` when the task finishes (`yujin.task.status({id})`
|
|
32
|
-
for the progress). Do NOT relaunch a run that already has a handle.
|
|
33
|
-
- And the corollary for any invocation that dies waiting: a verb call that
|
|
34
|
-
comes back UNANSWERED (E_VERB_CALL_UNANSWERED) did not necessarily fail.
|
|
35
|
-
Before redoing the work, LOOK FOR THE TRACE -- `yujin.evidence.list` for a
|
|
36
|
-
receipt, `yujin.task.list` for a task. Two closes were reported as
|
|
37
|
-
"believed" over a receipt that existed on disk the whole time.
|
|
38
|
-
|
|
39
|
-
## When does a project EXPECT a ladder?
|
|
40
|
-
|
|
41
|
-
Written here because the condition must be findable, not inferred from the
|
|
42
|
-
source (the owner's condition on F-06, 2026-11-01): "if tomorrow a project
|
|
43
|
-
should have a ladder and does not leave that trace, the notice does not
|
|
44
|
-
come out and we are where we started. The condition has to be WRITTEN
|
|
45
|
-
where someone would look for it."
|
|
46
|
-
|
|
47
|
-
The switch being ON means **the method is available**, not **you are
|
|
48
|
-
walking it**. It is ON by default in Forge developer, so injecting the
|
|
49
|
-
step block -- or warning that it is missing -- in every project with the
|
|
50
|
-
switch on would charge ~700 characters of system prompt per turn to
|
|
51
|
-
everyone who does not use the method.
|
|
52
|
-
|
|
53
|
-
So Forge warns ("enabled and NOT arriving") only when the project leaves a
|
|
54
|
-
TRACE that it expects a ladder. Exactly three traces count, any one of
|
|
55
|
-
them is enough (`expectsLadder` in `src/chat/urazuke_section.ts`):
|
|
56
|
-
|
|
57
|
-
1. **A Urazuke workflow instance exists** for the project, open or closed
|
|
58
|
-
(`findUrazukeInstance`). This is the normal trace: `yf urazuke start` /
|
|
59
|
-
`yujin.urazuke.start` leaves it.
|
|
60
|
-
2. **The frozen copy of the gate definition** is on disk
|
|
61
|
-
(`.forge/urazuke/gates.json`, PND-165): the project pinned a version of
|
|
62
|
-
the method, so it is using it.
|
|
63
|
-
3. **The method's artifacts are in the repository**: all three of
|
|
64
|
-
`docs/WORKING_AGREEMENT.md`, `docs/SEMANTIC_TREE.md` and `docs/GATES.md`
|
|
65
|
-
exist and are not stubs (`hasMethodArtifacts` in
|
|
66
|
-
`src/urazuke/probes.ts`).
|
|
67
|
-
|
|
68
|
-
With none of the three, the turn records `reason: 'not_in_use'` and stays
|
|
69
|
-
silent. That reason is itself the trace: it is in the result of
|
|
70
|
-
`buildUrazukeSection`, so "the notice did not come out" can always be
|
|
71
|
-
answered with WHICH condition failed. If you want the ladder in a project
|
|
72
|
-
that has none of the three, open it -- `yujin.urazuke.start` -- and the
|
|
73
|
-
step prompt arrives on the next turn.
|
|
74
|
-
|
|
75
|
-
## A forced close carries a TYPE, and the type is counted
|
|
76
|
-
|
|
77
|
-
M-02, decided by the owner on 2026-11-01. A plan item ships only with its
|
|
78
|
-
receipts, and some items have no red to produce at all (documentation,
|
|
79
|
-
configuration). The answer is NOT a kind of pending that authorises
|
|
80
|
-
itself -- nothing can guarantee a code item will not be declared
|
|
81
|
-
"documentation" -- it is an honest forced close that is COUNTABLE:
|
|
82
|
-
|
|
83
|
-
- `force_reason` (the owner's prose, min 15 chars) is still mandatory, and
|
|
84
|
-
- `force_kind` is mandatory with it, from a CLOSED catalogue
|
|
85
|
-
(`src/urazuke/overrides.ts`; `yf pending close --force-kind`, or
|
|
86
|
-
`force_kind` on `yujin.pending.close`). A free-text type turns the
|
|
87
|
-
counter into a cloud of synonyms, which is not counting.
|
|
88
|
-
|
|
89
|
-
The condition that makes this worth having, in the owner's words: "the
|
|
90
|
-
typed motive has to be a NUMBER in the report. You have to be able to ask
|
|
91
|
-
how many closes were forced by `documentacion_sin_rojo_posible` and get an
|
|
92
|
-
answer. If the type exists and nobody counts it, it is the same hole with
|
|
93
|
-
a better name -- and worse, because it sounds solved."
|
|
94
|
-
|
|
95
|
-
So the override is stored as DATA on the item's history entry
|
|
96
|
-
(`history[].override = {gate, kind, missing}`), and
|
|
97
|
-
`docs/RETROSPECTIVE_<date>.md` prints one row per motive and one per gate
|
|
98
|
-
bypassed. Overrides recorded before this change are still counted, in
|
|
99
|
-
their own `sin tipo` row: discounting them would have made the total DROP
|
|
100
|
-
on the day of the fix, which is the worst way to measure a debt.
|
|
101
|
-
|
|
102
|
-
## The catalogue's file names are PROTOCOL
|
|
103
|
-
|
|
104
|
-
Decided by the owner on 2026-11-01 (M-03, measured by the Urazuke
|
|
105
|
-
experiment), as a rule of the contract and not as an error message:
|
|
106
|
-
|
|
107
|
-
**The file names the step catalogue asks for are protocol and are NOT
|
|
108
|
-
translated. The CONTENT goes in the project's language.**
|
|
109
|
-
|
|
110
|
-
So a step that names `docs/ARCHITECTURE.md` is satisfied by a file at
|
|
111
|
-
exactly that path, whose prose may be entirely in Spanish. A
|
|
112
|
-
`docs/ARQUITECTURA.md` with the identical, correct content counts as
|
|
113
|
-
ABSENT -- and the gate now says so, with that reason, every time an
|
|
114
|
-
artifact is missing (`ARTIFACT_NAMES_ARE_PROTOCOL` in
|
|
115
|
-
`src/urazuke/gate.ts`), whether or not a similar-looking neighbour is
|
|
116
|
-
found next to it.
|
|
117
|
-
|
|
118
|
-
Why not a per-language alias table, which was the other option: **an alias
|
|
119
|
-
table is a second source of truth, and a second source of truth
|
|
120
|
-
desynchronises** -- the defect this project already has on record three
|
|
121
|
-
times. (Plus the price on the Forge side: 232 artifact names to maintain in
|
|
122
|
-
two languages.) It is the same line the `language-sovereignty` doctrine
|
|
123
|
-
draws for verb ids and code identifiers: translate the EXPERIENCE, never
|
|
124
|
-
the protocol.
|
|
125
|
-
|
|
126
|
-
What was unacceptable before this was never the requirement. It was the
|
|
127
|
-
SILENCE: a file with the right content next to it, counted as absent, with
|
|
128
|
-
no written reason.
|
|
129
|
-
|
|
130
|
-
## The five statuses, and why `closed` is NOT `green`
|
|
131
|
-
|
|
132
|
-
A step carries ONE of five statuses, and two of them are easy to confuse --
|
|
133
|
-
the confusion cost a report that said 0 of 24 when three steps were closed
|
|
134
|
-
(F-07, measured by the Urazuke experiment, 2026-11-01):
|
|
135
|
-
|
|
136
|
-
| status | meaning |
|
|
137
|
-
|--------------|--------------------------------------------------------------|
|
|
138
|
-
| `closed` | the canonical task of this step IS CLOSED. Consolidated progress. The BEST state a step can be in. |
|
|
139
|
-
| `green` | the gate passes and the task is STILL OPEN: it CAN be closed, nobody closed it yet. |
|
|
140
|
-
| `red` | a check is missing. It does not close. |
|
|
141
|
-
| `owner` | nothing mechanical to check; the owner signs it. |
|
|
142
|
-
| `unmeasured` | the definition in force needs an evaluator this installation cannot measure. It does NOT close and it is NOT green. |
|
|
143
|
-
|
|
144
|
-
The two rules that follow:
|
|
145
|
-
|
|
146
|
-
1. **`closed` and `green` are disjoint.** A closed step is reported as
|
|
147
|
-
`closed`, never as `green`. So **counting `green` to measure progress
|
|
148
|
-
LOSES every closed step** -- the best ones. Progress is `closed + green`
|
|
149
|
-
(`done_or_ready`), and a summary prints BOTH numbers, never one.
|
|
150
|
-
2. **Nobody counts statuses on their own.** `summarizeLadder()` in
|
|
151
|
-
`src/urazuke/current.ts` is the only counter; the verb, the CLI, the
|
|
152
|
-
retrospective and the cyclic report all read it. A second, independent
|
|
153
|
-
count is exactly the inference the method warns against: it is how the
|
|
154
|
-
distinction gets lost again, in one consumer, silently.
|
|
155
|
-
|
|
156
|
-
## How to work inside it
|
|
157
|
-
|
|
158
|
-
1. Read the URAZUKE section: red checks are what is missing. Produce the
|
|
159
|
-
artifact at the path named, with real content, or ask the owner for the
|
|
160
|
-
input that is theirs (`antes de enviar`). Never invent an owner input.
|
|
161
|
-
2. When the section says GREEN, close the task with `yujin.pending.close`
|
|
162
|
-
(full expediente) and the next step's prompt arrives on the next turn.
|
|
163
|
-
3. `yujin.urazuke.status` shows the whole ladder; `yujin.urazuke.step`
|
|
164
|
-
shows any step in full (prompts, inputs, artifacts, checklist).
|
|
165
|
-
4. The plan is the pendings: each item needs `spec` (acceptance "given /
|
|
166
|
-
when / then" + `how_verified`) before it is implemented (step 5).
|
|
167
|
-
5. No deadlines, ever: the method fixes the order and the gates, not the
|
|
168
|
-
calendar. Speed is a consequence, not the objective.
|
|
169
|
-
|
|
170
|
-
## The profiles axis: three evaluators, and where their data lives
|
|
171
|
-
|
|
172
|
-
Added 2026-11-01 (Pieza 6, D-044). The published definition requires these
|
|
173
|
-
three on the three anchors of the construction loop, and until that day this
|
|
174
|
-
installation could not measure any of them -- so adopting the published
|
|
175
|
-
definition froze three permanently unmeasurable steps.
|
|
176
|
-
|
|
177
|
-
| evaluator | step | what it measures |
|
|
178
|
-
|---|---|---|
|
|
179
|
-
| `pendings_profiles` | 5 | every open plan item that touches a screen declares its convergence group, the profiles that have it, and ONE acceptance criterion per profile |
|
|
180
|
-
| `profile_matrix` | 8 | the matrix is consistent, the navigation is DERIVED from it, and each profile's e2e reaches exactly its row |
|
|
181
|
-
| `manual_cases_per_profile` | 10 | every manual case ran once per affected profile, derived from the matrix |
|
|
182
|
-
|
|
183
|
-
The data, and the one rule that explains every choice -- **the matrix is the
|
|
184
|
-
producer**:
|
|
185
|
-
|
|
186
|
-
- `docs/PROFILE_MATRIX.md` carries the four columns of Annex H B2 and
|
|
187
|
-
nothing else: functionality, home, profiles, entry point. The table is
|
|
188
|
-
found by HEADER, so the column order is free.
|
|
189
|
-
- `.forge/profile-navigation.json` is the generated navigation, and it
|
|
190
|
-
declares a fingerprint. The evaluator **recomputes** that fingerprint from
|
|
191
|
-
the matrix and compares; it never reads the declared one and compares it
|
|
192
|
-
with itself, which would pass any file. The fingerprint is
|
|
193
|
-
self-describing (algorithm, encoding, canonical form, covers, excludes) --
|
|
194
|
-
one that cannot be reproduced from outside is not evidence.
|
|
195
|
-
- `.forge/profile-reachability.json` lists, per profile, what the e2e
|
|
196
|
-
**reached** (not what it attempted) and the id of its receipt. The
|
|
197
|
-
evaluator contrasts that id against the receipt registry: an artifact
|
|
198
|
-
whose receipt the registry does not have is prose.
|
|
199
|
-
- the two directions of "neither less nor more" fail DIFFERENTLY and never
|
|
200
|
-
merge into one red: reaching **less** than the row is a MISSING piece
|
|
201
|
-
(construction incomplete); reaching **more** is an AUTHORIZATION defect,
|
|
202
|
-
high severity by written definition. If the message does not name the
|
|
203
|
-
class, the reader under-rates it.
|
|
204
|
-
- the per-profile pending fields live in `PendingSpec` **in the registry**,
|
|
205
|
-
not in `docs/PENDING.md` (owner's decision, 2026-11-01): a gate cannot
|
|
206
|
-
measure prose, `pendings_spec` already measures there, and two sources for
|
|
207
|
-
the same datum age in opposite directions. The document is generated from
|
|
208
|
-
the registry or cites it. Write them with
|
|
209
|
-
`yf pending add --touches-screen --convergence-group ... --row-profile ...
|
|
210
|
-
--accept-for perfil=criterio`.
|
|
211
|
-
- `touches_screen` is a THREE-state field: absent means "not declared" and
|
|
212
|
-
the evaluator reports it as such -- never as "does not touch". Not looking
|
|
213
|
-
is not the same as nothing being there.
|
|
214
|
-
- the manual case ledger carries `functionality` (the link the method's
|
|
215
|
-
"derived from the matrix" implies): `yf urazuke rules sign <rule> passed
|
|
216
|
-
--by <name> --profile <id> --functionality "<row>"`. A case with a single
|
|
217
|
-
profile does NOT count as executed when its row has more.
|
|
218
|
-
|
|
219
|
-
To measure what adopting the published definition would cost BEFORE
|
|
220
|
-
adopting it: `yf urazuke rules show --published` (read only, writes
|
|
221
|
-
nothing, never blocks) and `yf urazuke gates pull`.
|
|
1
|
+
# Urazuke -- the evidence method, as Forge runs it
|
|
2
|
+
|
|
3
|
+
Urazuke (github.com/pkuschnirof/urazuke) is the method behind every project
|
|
4
|
+
Forge builds or maintains: 24 ordered steps in four stretches, each with an
|
|
5
|
+
exact prompt, the inputs the owner prepares, the artifacts the agent leaves
|
|
6
|
+
in the repository, and a completion check the owner does WITHOUT reading
|
|
7
|
+
code. An existing system built without it goes through eight normalisation
|
|
8
|
+
stations (N0..N7) first and enters the loop at step 5.
|
|
9
|
+
|
|
10
|
+
## What is mechanical (not prose)
|
|
11
|
+
|
|
12
|
+
- The project's workflow is `urazuke` (no code) or `urazuke-legacy` (code
|
|
13
|
+
without the method's artifacts). Every canonical task carries its step.
|
|
14
|
+
- The CURRENT step's prompt is injected into your system prompt every turn,
|
|
15
|
+
with the state of its checks (section "URAZUKE -- peldano NN"). Act on
|
|
16
|
+
that prompt as if the owner had pasted it. Do not skip ahead.
|
|
17
|
+
- A canonical task closes ONLY when `evaluateStep()` is GREEN: the files
|
|
18
|
+
the step names exist, are not stubs, say what they must; the sizing
|
|
19
|
+
record is admissible (G9); the plan items carry a spec; the evidence
|
|
20
|
+
receipts exist. `yujin.pending.close` refuses a red step. An override
|
|
21
|
+
needs the OWNER's written `force_reason` AND its `force_kind` (kept in
|
|
22
|
+
history, counted per motive -- see "A forced close carries a TYPE");
|
|
23
|
+
never pass either on your own initiative.
|
|
24
|
+
- Evidence is a RECEIPT Forge records (command, ref, exit code, counts),
|
|
25
|
+
never your summary. "Tests pass" without a receipt is a claim.
|
|
26
|
+
- A LONG run leaves its receipt the same way. `yujin.evidence.run` blocks
|
|
27
|
+
the turn only while the run fits the blocking window (10 min, lowered with
|
|
28
|
+
`limits.claude_cli_silence_ms`); over that, or with `background: true`, it
|
|
29
|
+
is launched detached and returns a HANDLE. That is not a degraded mode:
|
|
30
|
+
the receipt is written by whoever runs, not by whoever waits. Read it with
|
|
31
|
+
`yujin.evidence.list` when the task finishes (`yujin.task.status({id})`
|
|
32
|
+
for the progress). Do NOT relaunch a run that already has a handle.
|
|
33
|
+
- And the corollary for any invocation that dies waiting: a verb call that
|
|
34
|
+
comes back UNANSWERED (E_VERB_CALL_UNANSWERED) did not necessarily fail.
|
|
35
|
+
Before redoing the work, LOOK FOR THE TRACE -- `yujin.evidence.list` for a
|
|
36
|
+
receipt, `yujin.task.list` for a task. Two closes were reported as
|
|
37
|
+
"believed" over a receipt that existed on disk the whole time.
|
|
38
|
+
|
|
39
|
+
## When does a project EXPECT a ladder?
|
|
40
|
+
|
|
41
|
+
Written here because the condition must be findable, not inferred from the
|
|
42
|
+
source (the owner's condition on F-06, 2026-11-01): "if tomorrow a project
|
|
43
|
+
should have a ladder and does not leave that trace, the notice does not
|
|
44
|
+
come out and we are where we started. The condition has to be WRITTEN
|
|
45
|
+
where someone would look for it."
|
|
46
|
+
|
|
47
|
+
The switch being ON means **the method is available**, not **you are
|
|
48
|
+
walking it**. It is ON by default in Forge developer, so injecting the
|
|
49
|
+
step block -- or warning that it is missing -- in every project with the
|
|
50
|
+
switch on would charge ~700 characters of system prompt per turn to
|
|
51
|
+
everyone who does not use the method.
|
|
52
|
+
|
|
53
|
+
So Forge warns ("enabled and NOT arriving") only when the project leaves a
|
|
54
|
+
TRACE that it expects a ladder. Exactly three traces count, any one of
|
|
55
|
+
them is enough (`expectsLadder` in `src/chat/urazuke_section.ts`):
|
|
56
|
+
|
|
57
|
+
1. **A Urazuke workflow instance exists** for the project, open or closed
|
|
58
|
+
(`findUrazukeInstance`). This is the normal trace: `yf urazuke start` /
|
|
59
|
+
`yujin.urazuke.start` leaves it.
|
|
60
|
+
2. **The frozen copy of the gate definition** is on disk
|
|
61
|
+
(`.forge/urazuke/gates.json`, PND-165): the project pinned a version of
|
|
62
|
+
the method, so it is using it.
|
|
63
|
+
3. **The method's artifacts are in the repository**: all three of
|
|
64
|
+
`docs/WORKING_AGREEMENT.md`, `docs/SEMANTIC_TREE.md` and `docs/GATES.md`
|
|
65
|
+
exist and are not stubs (`hasMethodArtifacts` in
|
|
66
|
+
`src/urazuke/probes.ts`).
|
|
67
|
+
|
|
68
|
+
With none of the three, the turn records `reason: 'not_in_use'` and stays
|
|
69
|
+
silent. That reason is itself the trace: it is in the result of
|
|
70
|
+
`buildUrazukeSection`, so "the notice did not come out" can always be
|
|
71
|
+
answered with WHICH condition failed. If you want the ladder in a project
|
|
72
|
+
that has none of the three, open it -- `yujin.urazuke.start` -- and the
|
|
73
|
+
step prompt arrives on the next turn.
|
|
74
|
+
|
|
75
|
+
## A forced close carries a TYPE, and the type is counted
|
|
76
|
+
|
|
77
|
+
M-02, decided by the owner on 2026-11-01. A plan item ships only with its
|
|
78
|
+
receipts, and some items have no red to produce at all (documentation,
|
|
79
|
+
configuration). The answer is NOT a kind of pending that authorises
|
|
80
|
+
itself -- nothing can guarantee a code item will not be declared
|
|
81
|
+
"documentation" -- it is an honest forced close that is COUNTABLE:
|
|
82
|
+
|
|
83
|
+
- `force_reason` (the owner's prose, min 15 chars) is still mandatory, and
|
|
84
|
+
- `force_kind` is mandatory with it, from a CLOSED catalogue
|
|
85
|
+
(`src/urazuke/overrides.ts`; `yf pending close --force-kind`, or
|
|
86
|
+
`force_kind` on `yujin.pending.close`). A free-text type turns the
|
|
87
|
+
counter into a cloud of synonyms, which is not counting.
|
|
88
|
+
|
|
89
|
+
The condition that makes this worth having, in the owner's words: "the
|
|
90
|
+
typed motive has to be a NUMBER in the report. You have to be able to ask
|
|
91
|
+
how many closes were forced by `documentacion_sin_rojo_posible` and get an
|
|
92
|
+
answer. If the type exists and nobody counts it, it is the same hole with
|
|
93
|
+
a better name -- and worse, because it sounds solved."
|
|
94
|
+
|
|
95
|
+
So the override is stored as DATA on the item's history entry
|
|
96
|
+
(`history[].override = {gate, kind, missing}`), and
|
|
97
|
+
`docs/RETROSPECTIVE_<date>.md` prints one row per motive and one per gate
|
|
98
|
+
bypassed. Overrides recorded before this change are still counted, in
|
|
99
|
+
their own `sin tipo` row: discounting them would have made the total DROP
|
|
100
|
+
on the day of the fix, which is the worst way to measure a debt.
|
|
101
|
+
|
|
102
|
+
## The catalogue's file names are PROTOCOL
|
|
103
|
+
|
|
104
|
+
Decided by the owner on 2026-11-01 (M-03, measured by the Urazuke
|
|
105
|
+
experiment), as a rule of the contract and not as an error message:
|
|
106
|
+
|
|
107
|
+
**The file names the step catalogue asks for are protocol and are NOT
|
|
108
|
+
translated. The CONTENT goes in the project's language.**
|
|
109
|
+
|
|
110
|
+
So a step that names `docs/ARCHITECTURE.md` is satisfied by a file at
|
|
111
|
+
exactly that path, whose prose may be entirely in Spanish. A
|
|
112
|
+
`docs/ARQUITECTURA.md` with the identical, correct content counts as
|
|
113
|
+
ABSENT -- and the gate now says so, with that reason, every time an
|
|
114
|
+
artifact is missing (`ARTIFACT_NAMES_ARE_PROTOCOL` in
|
|
115
|
+
`src/urazuke/gate.ts`), whether or not a similar-looking neighbour is
|
|
116
|
+
found next to it.
|
|
117
|
+
|
|
118
|
+
Why not a per-language alias table, which was the other option: **an alias
|
|
119
|
+
table is a second source of truth, and a second source of truth
|
|
120
|
+
desynchronises** -- the defect this project already has on record three
|
|
121
|
+
times. (Plus the price on the Forge side: 232 artifact names to maintain in
|
|
122
|
+
two languages.) It is the same line the `language-sovereignty` doctrine
|
|
123
|
+
draws for verb ids and code identifiers: translate the EXPERIENCE, never
|
|
124
|
+
the protocol.
|
|
125
|
+
|
|
126
|
+
What was unacceptable before this was never the requirement. It was the
|
|
127
|
+
SILENCE: a file with the right content next to it, counted as absent, with
|
|
128
|
+
no written reason.
|
|
129
|
+
|
|
130
|
+
## The five statuses, and why `closed` is NOT `green`
|
|
131
|
+
|
|
132
|
+
A step carries ONE of five statuses, and two of them are easy to confuse --
|
|
133
|
+
the confusion cost a report that said 0 of 24 when three steps were closed
|
|
134
|
+
(F-07, measured by the Urazuke experiment, 2026-11-01):
|
|
135
|
+
|
|
136
|
+
| status | meaning |
|
|
137
|
+
|--------------|--------------------------------------------------------------|
|
|
138
|
+
| `closed` | the canonical task of this step IS CLOSED. Consolidated progress. The BEST state a step can be in. |
|
|
139
|
+
| `green` | the gate passes and the task is STILL OPEN: it CAN be closed, nobody closed it yet. |
|
|
140
|
+
| `red` | a check is missing. It does not close. |
|
|
141
|
+
| `owner` | nothing mechanical to check; the owner signs it. |
|
|
142
|
+
| `unmeasured` | the definition in force needs an evaluator this installation cannot measure. It does NOT close and it is NOT green. |
|
|
143
|
+
|
|
144
|
+
The two rules that follow:
|
|
145
|
+
|
|
146
|
+
1. **`closed` and `green` are disjoint.** A closed step is reported as
|
|
147
|
+
`closed`, never as `green`. So **counting `green` to measure progress
|
|
148
|
+
LOSES every closed step** -- the best ones. Progress is `closed + green`
|
|
149
|
+
(`done_or_ready`), and a summary prints BOTH numbers, never one.
|
|
150
|
+
2. **Nobody counts statuses on their own.** `summarizeLadder()` in
|
|
151
|
+
`src/urazuke/current.ts` is the only counter; the verb, the CLI, the
|
|
152
|
+
retrospective and the cyclic report all read it. A second, independent
|
|
153
|
+
count is exactly the inference the method warns against: it is how the
|
|
154
|
+
distinction gets lost again, in one consumer, silently.
|
|
155
|
+
|
|
156
|
+
## How to work inside it
|
|
157
|
+
|
|
158
|
+
1. Read the URAZUKE section: red checks are what is missing. Produce the
|
|
159
|
+
artifact at the path named, with real content, or ask the owner for the
|
|
160
|
+
input that is theirs (`antes de enviar`). Never invent an owner input.
|
|
161
|
+
2. When the section says GREEN, close the task with `yujin.pending.close`
|
|
162
|
+
(full expediente) and the next step's prompt arrives on the next turn.
|
|
163
|
+
3. `yujin.urazuke.status` shows the whole ladder; `yujin.urazuke.step`
|
|
164
|
+
shows any step in full (prompts, inputs, artifacts, checklist).
|
|
165
|
+
4. The plan is the pendings: each item needs `spec` (acceptance "given /
|
|
166
|
+
when / then" + `how_verified`) before it is implemented (step 5).
|
|
167
|
+
5. No deadlines, ever: the method fixes the order and the gates, not the
|
|
168
|
+
calendar. Speed is a consequence, not the objective.
|
|
169
|
+
|
|
170
|
+
## The profiles axis: three evaluators, and where their data lives
|
|
171
|
+
|
|
172
|
+
Added 2026-11-01 (Pieza 6, D-044). The published definition requires these
|
|
173
|
+
three on the three anchors of the construction loop, and until that day this
|
|
174
|
+
installation could not measure any of them -- so adopting the published
|
|
175
|
+
definition froze three permanently unmeasurable steps.
|
|
176
|
+
|
|
177
|
+
| evaluator | step | what it measures |
|
|
178
|
+
|---|---|---|
|
|
179
|
+
| `pendings_profiles` | 5 | every open plan item that touches a screen declares its convergence group, the profiles that have it, and ONE acceptance criterion per profile |
|
|
180
|
+
| `profile_matrix` | 8 | the matrix is consistent, the navigation is DERIVED from it, and each profile's e2e reaches exactly its row |
|
|
181
|
+
| `manual_cases_per_profile` | 10 | every manual case ran once per affected profile, derived from the matrix |
|
|
182
|
+
|
|
183
|
+
The data, and the one rule that explains every choice -- **the matrix is the
|
|
184
|
+
producer**:
|
|
185
|
+
|
|
186
|
+
- `docs/PROFILE_MATRIX.md` carries the four columns of Annex H B2 and
|
|
187
|
+
nothing else: functionality, home, profiles, entry point. The table is
|
|
188
|
+
found by HEADER, so the column order is free.
|
|
189
|
+
- `.forge/profile-navigation.json` is the generated navigation, and it
|
|
190
|
+
declares a fingerprint. The evaluator **recomputes** that fingerprint from
|
|
191
|
+
the matrix and compares; it never reads the declared one and compares it
|
|
192
|
+
with itself, which would pass any file. The fingerprint is
|
|
193
|
+
self-describing (algorithm, encoding, canonical form, covers, excludes) --
|
|
194
|
+
one that cannot be reproduced from outside is not evidence.
|
|
195
|
+
- `.forge/profile-reachability.json` lists, per profile, what the e2e
|
|
196
|
+
**reached** (not what it attempted) and the id of its receipt. The
|
|
197
|
+
evaluator contrasts that id against the receipt registry: an artifact
|
|
198
|
+
whose receipt the registry does not have is prose.
|
|
199
|
+
- the two directions of "neither less nor more" fail DIFFERENTLY and never
|
|
200
|
+
merge into one red: reaching **less** than the row is a MISSING piece
|
|
201
|
+
(construction incomplete); reaching **more** is an AUTHORIZATION defect,
|
|
202
|
+
high severity by written definition. If the message does not name the
|
|
203
|
+
class, the reader under-rates it.
|
|
204
|
+
- the per-profile pending fields live in `PendingSpec` **in the registry**,
|
|
205
|
+
not in `docs/PENDING.md` (owner's decision, 2026-11-01): a gate cannot
|
|
206
|
+
measure prose, `pendings_spec` already measures there, and two sources for
|
|
207
|
+
the same datum age in opposite directions. The document is generated from
|
|
208
|
+
the registry or cites it. Write them with
|
|
209
|
+
`yf pending add --touches-screen --convergence-group ... --row-profile ...
|
|
210
|
+
--accept-for perfil=criterio`.
|
|
211
|
+
- `touches_screen` is a THREE-state field: absent means "not declared" and
|
|
212
|
+
the evaluator reports it as such -- never as "does not touch". Not looking
|
|
213
|
+
is not the same as nothing being there.
|
|
214
|
+
- the manual case ledger carries `functionality` (the link the method's
|
|
215
|
+
"derived from the matrix" implies): `yf urazuke rules sign <rule> passed
|
|
216
|
+
--by <name> --profile <id> --functionality "<row>"`. A case with a single
|
|
217
|
+
profile does NOT count as executed when its row has more.
|
|
218
|
+
|
|
219
|
+
To measure what adopting the published definition would cost BEFORE
|
|
220
|
+
adopting it: `yf urazuke rules show --published` (read only, writes
|
|
221
|
+
nothing, never blocks) and `yf urazuke gates pull`.
|