@jabworks/condux 0.28.0 → 0.30.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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@jabworks/condux",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.0",
|
|
4
4
|
"description": "OpenCode plugin for the condux workflow toolkit — bundles the condux skills and injects the specialist agents (coder, explorer, planner, researcher) plus an opt-in plan-review listener.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"publishConfig": {
|
|
@@ -20,7 +20,7 @@ between "the pipeline passed" and "I watched it do the thing".
|
|
|
20
20
|
|
|
21
21
|
| Change touches | Run this? |
|
|
22
22
|
|---|---|
|
|
23
|
-
| A rendered surface — page, component, story, dialog | **Yes** |
|
|
23
|
+
| A rendered surface — page, component, story, dialog, a mobile app screen | **Yes** |
|
|
24
24
|
| An endpoint, procedure, or CLI a human will call | **Yes** |
|
|
25
25
|
| Behaviour behind a flag or a state the tests don't reach | **Yes** |
|
|
26
26
|
| Types, docs, comments, config with no runtime effect | No — say so and skip |
|
|
@@ -43,6 +43,14 @@ Do not assume a dev server. In order:
|
|
|
43
43
|
Start it in the background, wait for it to actually serve (poll the URL — do
|
|
44
44
|
not `sleep` and hope), and note the URL in the report.
|
|
45
45
|
|
|
46
|
+
**Mobile app: load the native recipe.** If the project is a mobile app —
|
|
47
|
+
finalize's native-change test: an `expo` or `react-native` dependency, or a
|
|
48
|
+
committed `android/` or `ios/` — read `references/native-app.md` now. Its
|
|
49
|
+
target order replaces the list above; it picks the driving rung once (adb,
|
|
50
|
+
`agent-device`, mobile-mcp, Expo's skills — recommended, never installed) and
|
|
51
|
+
resolves `adb` to an absolute path. The claims, verdicts and report below are
|
|
52
|
+
unchanged.
|
|
53
|
+
|
|
46
54
|
**Mobile app: rebuild first when the change is native.** If finalize's
|
|
47
55
|
`Native` line said *native rebuild* (or the diff touches the native layer —
|
|
48
56
|
see finalize's native-change check), the installed app does not contain the
|
|
@@ -81,6 +89,12 @@ Order of checks, because this is where the defects were:
|
|
|
81
89
|
4. **Keyboard.** Tab to it, Escape out of it, confirm focus lands somewhere
|
|
82
90
|
sensible.
|
|
83
91
|
|
|
92
|
+
**Mobile app:** the same four checks, translated — both themes via
|
|
93
|
+
`cmd uimode night`; pressed, disabled and in-flight states in place of hover;
|
|
94
|
+
the failure path in airplane mode; the system back (`keyevent 4`) in place of
|
|
95
|
+
Tab and Escape, which must close what it opened. Every tap follows
|
|
96
|
+
`native-app.md`'s stale-UI rules.
|
|
97
|
+
|
|
84
98
|
### Step 4 — Capture evidence
|
|
85
99
|
|
|
86
100
|
One artifact per claim that has a visual or observable outcome — screenshot,
|
|
@@ -91,6 +105,12 @@ evidence file for the claim it supports and reference it from the report's
|
|
|
91
105
|
claim table. Console errors and failed network requests seen along the way
|
|
92
106
|
get reported even when they belong to another feature.
|
|
93
107
|
|
|
108
|
+
**Mobile app:** evidence is a screenshot you have read back, or a recording
|
|
109
|
+
for motion, and `native-app.md`'s log sweep stands in for console and network.
|
|
110
|
+
A claim the emulator cannot settle — haptics, camera, push, feel — gets the
|
|
111
|
+
`device-only` verdict and a line under the report's `For the phone:`, never ✓.
|
|
112
|
+
The report adds the `Device` and `Build` header keys.
|
|
113
|
+
|
|
94
114
|
Then write `report.md` into the same dir, in the shape of
|
|
95
115
|
`references/report-template.md` — every run writes one, including runs where
|
|
96
116
|
nothing could be driven (the template carries the fallback shape).
|
|
@@ -127,11 +147,16 @@ Wait timed out
|
|
|
127
147
|
|
|
128
148
|
Two failed attempts on the same claim is the ceiling. Report and move on.
|
|
129
149
|
|
|
150
|
+
On a mobile app, the device-side failures — an offline device, an emulator
|
|
151
|
+
that won't boot, a stale binary — are in `native-app.md`'s part 8, under the
|
|
152
|
+
same ceiling.
|
|
153
|
+
|
|
130
154
|
## Output Format
|
|
131
155
|
|
|
132
|
-
The report shape — the fixed header table (Date / Target / Diff / Themes
|
|
133
|
-
the claim table (Claim | Evidence |
|
|
134
|
-
|
|
156
|
+
The report shape — the fixed header table (Date / Target / Diff / Themes,
|
|
157
|
+
plus Device / Build on a native app run), the claim table (Claim | Evidence |
|
|
158
|
+
Verdict), the phone checklist for `device-only` claims, "Also seen", and the
|
|
159
|
+
outcome line — lives in `references/report-template.md`, the canonical home. It also
|
|
135
160
|
carries the fallback shape for when nothing could be driven; that run still
|
|
136
161
|
writes `report.md`, because an absent report is indistinguishable from a run
|
|
137
162
|
that never happened. Fixed header keys and a fixed claim-table shape are what
|
|
@@ -142,7 +167,8 @@ make two runs of the same surface comparable.
|
|
|
142
167
|
```
|
|
143
168
|
✗ Reporting a claim as verified because the code looks right
|
|
144
169
|
✗ Inventing a screenshot, a response, or a result that wasn't observed
|
|
145
|
-
✗ Installing a browser driver or scaffolding a test harness to get a result
|
|
170
|
+
✗ Installing a browser or device driver, or scaffolding a test harness to get a result
|
|
171
|
+
✗ Reporting a device-only claim as ✓
|
|
146
172
|
✗ sleep-then-check instead of polling for the condition
|
|
147
173
|
✗ Retrying the same selector more than twice
|
|
148
174
|
✗ Killing processes the run didn't start
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# Native app verification (Android)
|
|
2
|
+
|
|
3
|
+
Loaded from Step 1 when the project is a mobile app — the same test as
|
|
4
|
+
finalize's native-change check: an `expo` or `react-native` dependency in
|
|
5
|
+
`package.json`, or a committed `android/` or `ios/` directory. A web project
|
|
6
|
+
never reads this file.
|
|
7
|
+
|
|
8
|
+
The claim/verdict/report contract in SKILL.md does not change. This file only
|
|
9
|
+
says how to reach the app, drive it, and read its errors — and which claims an
|
|
10
|
+
emulator cannot settle.
|
|
11
|
+
|
|
12
|
+
## 1. Pick the rung
|
|
13
|
+
|
|
14
|
+
Decide once, at the start of the run, and name the choice in the report's
|
|
15
|
+
`Target` row. Three rungs, each optional, none ever installed by you:
|
|
16
|
+
|
|
17
|
+
| Concern | Use, first match wins |
|
|
18
|
+
|---|---|
|
|
19
|
+
| Build and install | the `expo` plugin's `expo-dev-client` / `eas-simulator` skills, when they are in your skill list → the project's own build script → `npx expo run:android` |
|
|
20
|
+
| Drive and read logs | `agent-device` on PATH (`command -v agent-device`) → mobile-mcp's `mobile_*` tools, when you have them → the core adb recipe below |
|
|
21
|
+
|
|
22
|
+
When a driver rung is in use, follow **its** documentation for the commands
|
|
23
|
+
(`agent-device help`, its bundled skills, the MCP tools' own descriptions) —
|
|
24
|
+
this file deliberately does not restate them. Parts 5–7 below apply on every
|
|
25
|
+
rung: they are about what counts as evidence, not about which tool taps.
|
|
26
|
+
|
|
27
|
+
No driver installed is the normal case, not a gap — never install one, and
|
|
28
|
+
never stop the run to ask.
|
|
29
|
+
|
|
30
|
+
## 2. Target
|
|
31
|
+
|
|
32
|
+
In order, before booting or building anything:
|
|
33
|
+
|
|
34
|
+
1. **The project's own setup wins.** `AGENTS.md`, `README.md`, a
|
|
35
|
+
project-local skill for running the app, `package.json` scripts
|
|
36
|
+
(`android`, `start`, a dev-client script), and anything under `scripts/`
|
|
37
|
+
that boots an emulator or installs a build. Use them as written. When they
|
|
38
|
+
disagree, the prose that is newest wins over a script name — a script can
|
|
39
|
+
outlive the emulator it boots.
|
|
40
|
+
2. **Is a device already attached?** `adb devices` (with the resolved path,
|
|
41
|
+
part 3). One device in the `device` state → use it. `offline` or
|
|
42
|
+
`unauthorized` → part 8.
|
|
43
|
+
3. **No device** → boot the emulator the project's script names, or
|
|
44
|
+
`emulator -list-avds` and the first one. Poll until
|
|
45
|
+
`adb shell getprop sys.boot_completed` prints `1` — never a fixed sleep.
|
|
46
|
+
4. **Metro.** A dev client loads JS from Metro: check port 8081 before
|
|
47
|
+
starting it, and run `adb reverse tcp:8081 tcp:8081` once per boot.
|
|
48
|
+
5. **Package and scheme.** Read `android.package` and `scheme` from the app
|
|
49
|
+
config (`app.json` / `app.config.*`), or `applicationId` from
|
|
50
|
+
`android/app/build.gradle*`. Every launch and log filter below needs them.
|
|
51
|
+
An `app.config.*` can change both per build variant (a dev client often
|
|
52
|
+
carries a `.dev` suffix and its own scheme) — confirm the installed one
|
|
53
|
+
with `adb shell pm list packages <name>` before launching.
|
|
54
|
+
|
|
55
|
+
## 3. Resolve adb once
|
|
56
|
+
|
|
57
|
+
`adb` is often on the user's interactive PATH only, and an agent's shell keeps
|
|
58
|
+
no state between calls — an `export PATH=…` or an `ADB=…` variable lasts one
|
|
59
|
+
command.
|
|
60
|
+
|
|
61
|
+
**A project-provided adb wins.** Some setups run the emulators on another
|
|
62
|
+
host or OS and reach them through a wrapper script or a non-default adb
|
|
63
|
+
server; the project's docs (part 2) name it. Use that, by absolute path.
|
|
64
|
+
Otherwise resolve the absolute path once:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
command -v adb || ls "$ANDROID_HOME/platform-tools/adb" "$ANDROID_SDK_ROOT/platform-tools/adb" 2>/dev/null | head -1
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then **write that literal path into every later command**. An adb that lists
|
|
71
|
+
no devices while the project documents a running one is the wrong adb, not an
|
|
72
|
+
empty machine — go back to the project's docs. Nothing found →
|
|
73
|
+
stop and report the blocker with the exact next command to try (set
|
|
74
|
+
`ANDROID_HOME`, or install platform-tools). Never install the SDK yourself.
|
|
75
|
+
|
|
76
|
+
## 4. Drive
|
|
77
|
+
|
|
78
|
+
The core recipe, written with `adb` for brevity — use the resolved path.
|
|
79
|
+
|
|
80
|
+
| Need | Command |
|
|
81
|
+
|---|---|
|
|
82
|
+
| Launch at a screen | `adb shell am start -W -a android.intent.action.VIEW -d "<scheme>://<path>" <package>` |
|
|
83
|
+
| Tap / swipe | `adb shell input tap <x> <y>` · `adb shell input swipe <x1> <y1> <x2> <y2> <ms>` |
|
|
84
|
+
| Long-press | `adb shell input swipe <x> <y> <x> <y> 800` (a swipe that does not move) |
|
|
85
|
+
| Drag, multi-step gestures | `adb shell input motionevent DOWN/MOVE/UP <x> <y>`, where the device's `input` lists it |
|
|
86
|
+
| Type / keys | `adb shell input text '<text>'` · `adb shell input keyevent 4` (back) |
|
|
87
|
+
| Screenshot | `adb exec-out screencap -p > <claim>.png` — then Read the PNG; an unread screenshot proves nothing |
|
|
88
|
+
| Motion | `adb shell screenrecord --time-limit <s> /sdcard/<claim>.mp4`, then `adb pull` — a still cannot prove an animation |
|
|
89
|
+
| UI tree | `adb exec-out uiautomator dump /dev/tty` — element text, ids and `bounds` |
|
|
90
|
+
| Theme | `adb shell cmd uimode night yes` / `no` — both themes still gate a themed change |
|
|
91
|
+
| Offline | `adb shell cmd connectivity airplane-mode enable` / `disable` |
|
|
92
|
+
| Fresh state | `adb shell pm clear <package>` — only when the claim needs it; it wipes the user's app data |
|
|
93
|
+
|
|
94
|
+
## 5. Stale UI
|
|
95
|
+
|
|
96
|
+
Most wrong taps in the field came from acting on a picture of a screen that
|
|
97
|
+
had already changed.
|
|
98
|
+
|
|
99
|
+
- **Take a fresh screenshot before any tap that changes state**, and look at it.
|
|
100
|
+
- **A `uiautomator dump` is true only for the moment it ran.** Re-dump after
|
|
101
|
+
every navigation, dialog, or list change.
|
|
102
|
+
- **Coordinates come from a dump's `bounds`**, never estimated from an image.
|
|
103
|
+
- **"could not get idle state"** means an animation is running. Poll the dump
|
|
104
|
+
again; a screen that never goes idle is a finding, not a reason to guess.
|
|
105
|
+
|
|
106
|
+
## 6. Log sweep
|
|
107
|
+
|
|
108
|
+
Runtime errors are part of the evidence — the same rule as the browser
|
|
109
|
+
console.
|
|
110
|
+
|
|
111
|
+
1. Before driving: `adb logcat -c`.
|
|
112
|
+
2. After driving, the app's errors: `adb logcat -d -v time --pid=$(adb shell pidof -s <package>) '*:E'`.
|
|
113
|
+
3. The JS layer: `adb logcat -d -v time -s ReactNativeJS:V`, plus Metro's own output.
|
|
114
|
+
4. The app is gone (no pid) → it crashed: `adb logcat -d -b crash`. A crash on a
|
|
115
|
+
claim's path fails that claim.
|
|
116
|
+
|
|
117
|
+
A LogBox or RedBox overlay is a finding: read it, record its message, then
|
|
118
|
+
dismiss it. A RedBox on a claim's path fails that claim. Everything found here
|
|
119
|
+
goes in the report's "Also seen", even when it belongs to another feature.
|
|
120
|
+
|
|
121
|
+
## 7. What the emulator can't prove
|
|
122
|
+
|
|
123
|
+
These claims get the **`device-only`** verdict, with the reason, and go on the
|
|
124
|
+
report's phone checklist. Never ✓, whatever the emulator showed:
|
|
125
|
+
|
|
126
|
+
| Claim touches | Why the emulator can't settle it |
|
|
127
|
+
|---|---|
|
|
128
|
+
| Haptics | no vibration hardware |
|
|
129
|
+
| Camera, QR scanning, biometrics | simulated sources, not the real sensor path |
|
|
130
|
+
| Push notification delivery | needs real FCM delivery on a signed-in device |
|
|
131
|
+
| Feel — scroll, animation smoothness, startup time | judged on the slowest device you support, on a release build |
|
|
132
|
+
| Sensors — GPS movement, motion, NFC, Bluetooth | mocked or absent |
|
|
133
|
+
|
|
134
|
+
The emulator can still verify the *surrounding* behaviour — the button that
|
|
135
|
+
triggers the haptic, the screen the scan result lands on. Split such a claim
|
|
136
|
+
in two rather than giving the whole thing one verdict.
|
|
137
|
+
|
|
138
|
+
## 8. When it goes wrong
|
|
139
|
+
|
|
140
|
+
Environmental failures are results, not things to retry into the ground. The
|
|
141
|
+
two-attempt ceiling from SKILL.md applies.
|
|
142
|
+
|
|
143
|
+
| Failure | Response |
|
|
144
|
+
|---|---|
|
|
145
|
+
| `device offline` / `unauthorized` | one `adb reconnect`; still failing → report it |
|
|
146
|
+
| Emulator won't boot, or no AVD exists | report it with the next command to try; never kill an emulator you did not start |
|
|
147
|
+
| Metro port taken | report it; do not kill the process holding it |
|
|
148
|
+
| The app shows old behaviour | the binary is stale — Step 1's rebuild-first rule; record what you drove in the `Build` key |
|
|
149
|
+
| A tap does nothing | re-dump (part 5) and retry once; second miss → claim unchecked |
|
|
150
|
+
|
|
151
|
+
## 9. iOS
|
|
152
|
+
|
|
153
|
+
The core recipe is Android-only. It has not been verified against the iOS
|
|
154
|
+
simulator, so this file does not pretend to cover it. For an iOS claim: use
|
|
155
|
+
the driver rung (agent-device and mobile-mcp both drive the simulator) when
|
|
156
|
+
one is present; otherwise report the claim **unchecked** with the blocker
|
|
157
|
+
named — "no iOS driver; the core recipe is Android-only".
|
|
@@ -27,6 +27,37 @@ Also seen: <console errors, failed requests, off-feature breakage — or "nothin
|
|
|
27
27
|
<n> claims failed. <fix + re-verify note, or "all green">
|
|
28
28
|
```
|
|
29
29
|
|
|
30
|
+
A **native app run** (SKILL.md Step 1 detected a mobile app) adds two header
|
|
31
|
+
keys and one block, and has a fourth verdict:
|
|
32
|
+
|
|
33
|
+
```markdown
|
|
34
|
+
# Live verification: <change>
|
|
35
|
+
|
|
36
|
+
| | |
|
|
37
|
+
|---|---|
|
|
38
|
+
| Date | YYYY-MM-DD |
|
|
39
|
+
| Target | <package> on <device> via <rung: adb / agent-device / mobile-mcp> |
|
|
40
|
+
| Device | <emulator AVD + API level, or the physical model> |
|
|
41
|
+
| Build | JS only / rebuilt at <commit> (from finalize's Native line) |
|
|
42
|
+
| Diff | <branch or commit under test> |
|
|
43
|
+
| Themes | light ✓ dark ✓ |
|
|
44
|
+
|
|
45
|
+
| Claim | Evidence | Verdict |
|
|
46
|
+
|---|---|---|
|
|
47
|
+
| <behavior asserted, one line> | <file in this dir, or —> | ✓ / ✗ <what actually happened> |
|
|
48
|
+
| <hardware-bound behavior> | <file, or —> | device-only — <why the emulator can't show it> |
|
|
49
|
+
|
|
50
|
+
For the phone:
|
|
51
|
+
- [ ] <claim> — <what to do on the device> — passes when <what you observe>
|
|
52
|
+
|
|
53
|
+
Also seen: <logcat errors, LogBox/RedBox messages, Metro errors — or "nothing">
|
|
54
|
+
|
|
55
|
+
<n> failed · <m> device-only (on the phone list) · <k> verified. <fix + re-verify note>
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`For the phone:` carries one checkbox per `device-only` row and is omitted
|
|
59
|
+
when there are none. A web run never shows `Device`, `Build`, or this block.
|
|
60
|
+
|
|
30
61
|
When nothing could be driven, the report is still written — an absent
|
|
31
62
|
`report.md` is indistinguishable from a run that never happened:
|
|
32
63
|
|
|
@@ -50,5 +81,6 @@ When nothing could be driven, the report is still written — an absent
|
|
|
50
81
|
|---|---|
|
|
51
82
|
| Everything a run produces lives inside its run dir — nothing at the verification root | Root-level orphans belonging to no run were observed in the wild; the dir is the unit of a run |
|
|
52
83
|
| Evidence files are named for the claim they support and referenced from the claim table | The table is the index — an evidence file it doesn't reference is uncontextualized in a week |
|
|
53
|
-
| Header keys are fixed: Date, Target, Diff, Themes (Themes only for UI surfaces) | Two runs of the same surface are diffable only when their headers line up |
|
|
84
|
+
| Header keys are fixed: Date, Target, Diff, Themes (Themes only for UI surfaces); a native app run adds Device and Build | Two runs of the same surface are diffable only when their headers line up |
|
|
85
|
+
| `device-only` is a verdict, not a pass — it never counts toward verified, and every one lands on the phone checklist | "Never report hardware validation that was not performed": a deferred check written as ✓ is read as done |
|
|
54
86
|
| Every run writes `report.md`, including runs where nothing could be driven | Absence of a report must mean absence of a run, nothing else |
|
|
@@ -49,6 +49,12 @@ Run through this checklist. Every item must be answered honestly — not optimis
|
|
|
49
49
|
│ No console.log, no debug code, no TODO comments that │
|
|
50
50
|
│ weren't there before, no commented-out blocks. │
|
|
51
51
|
│ │
|
|
52
|
+
│ □ NO WORKAROUNDS │
|
|
53
|
+
│ Did anything here bypass a convention, widen a type, │
|
|
54
|
+
│ disable a rule, or special-case around a design just to │
|
|
55
|
+
│ make it land? Report it — the user decides whether it │
|
|
56
|
+
│ ships. Nothing bypassed → N/A, no commentary. │
|
|
57
|
+
│ │
|
|
52
58
|
│ □ READY FOR FINALIZE │
|
|
53
59
|
│ All the above are yes → call /finalize │
|
|
54
60
|
│ Any are no → fix first, then re-check │
|
|
@@ -100,6 +106,7 @@ a preflight failure like any other.
|
|
|
100
106
|
| "The edge cases are unlikely" | They happen in production. Consider them now. |
|
|
101
107
|
| "The plan steps were mostly done" | Mostly done is not done. |
|
|
102
108
|
| "I only changed one line, nothing could break" | One-line changes cause regressions too. |
|
|
109
|
+
| "It's a small workaround, I'll do it properly later" | Later is a PR nobody opens. Report it; the user chooses. |
|
|
103
110
|
|
|
104
111
|
## Output
|
|
105
112
|
|
|
@@ -112,6 +119,7 @@ a preflight failure like any other.
|
|
|
112
119
|
□ Spec drift ✓ / ✗ / N/A [notes] (N/A = no spec for this task)
|
|
113
120
|
□ No regressions ✓ / ✗ [notes]
|
|
114
121
|
□ Nothing left behind ✓ / ✗ [notes]
|
|
122
|
+
□ No workarounds ✓ / ✗ / N/A [notes] (N/A = nothing bypassed)
|
|
115
123
|
|
|
116
124
|
→ Ready for /finalize [YES / NO — list blockers if NO]
|
|
117
125
|
```
|
package/skills/workflow/SKILL.md
CHANGED
|
@@ -42,6 +42,11 @@ Condux is **lean and proportional** — the opposite of "always run every gate."
|
|
|
42
42
|
6. **House style rides along.** Before the first line of code in any tier, load
|
|
43
43
|
the `coding-directive` skill if it is installed — skip silently when it
|
|
44
44
|
isn't. Codebase mimicry and repo config still win over the directive.
|
|
45
|
+
7. **Two tracks, one of them triggered.** Tactical is the task in front of you.
|
|
46
|
+
Strategic is the environment that produced it — would a narrower type, a
|
|
47
|
+
lint rule, or a written convention have made this task's bug impossible?
|
|
48
|
+
The strategic track is *not* a standing obligation; that would violate rule
|
|
49
|
+
1. It fires on a trigger, and the triggers are in Environment Hardening.
|
|
45
50
|
|
|
46
51
|
## Entry Contract
|
|
47
52
|
|
|
@@ -151,7 +156,7 @@ UIs), the combined menu must still carry the full CP-1 option set.
|
|
|
151
156
|
|
|
152
157
|
| Option | What it does |
|
|
153
158
|
|---|---|
|
|
154
|
-
| **Verify it live** *(recommended when the change has a runnable surface)* | Load `live-verification` — drive the real UI or
|
|
159
|
+
| **Verify it live** *(recommended when the change has a runnable surface — an app on an emulator counts)* | Load the `live-verification` skill and follow it — including on a mobile app: drive the real UI, endpoint or emulator, check each claim against observed behaviour, and write its report |
|
|
155
160
|
| **Code review** *(recommended)* | `/code-review` the diff before merging |
|
|
156
161
|
| **Commit** | Load the `git-commit` skill if installed (conventional message from the diff, safe staging); otherwise follow the repo's commit conventions |
|
|
157
162
|
| **Cut a release** | Load the `release` skill if installed — machinery detection, dry-run plan, then tag → push → GitHub release; otherwise follow the repo's release conventions |
|
|
@@ -253,6 +258,38 @@ Scope turns out bigger than the confirmed tier? Stop immediately, report what yo
|
|
|
253
258
|
found ("this touches auth middleware, not just the UI"), re-confirm the tier before
|
|
254
259
|
continuing. Never silently expand scope.
|
|
255
260
|
|
|
261
|
+
## Environment Hardening
|
|
262
|
+
|
|
263
|
+
The strategic track, fired by a trigger rather than run on every task. Two
|
|
264
|
+
triggers, both observed rather than imagined:
|
|
265
|
+
|
|
266
|
+
- **Repeated friction.** The same obstacle cost time twice — twice in this
|
|
267
|
+
task, or once here and once earlier in the session.
|
|
268
|
+
- **A workaround taken.** You bypassed a convention, widened a type, disabled a
|
|
269
|
+
rule, or special-cased around a design to make the change land. `preflight`'s
|
|
270
|
+
no-workarounds box catches the ones you stopped noticing.
|
|
271
|
+
|
|
272
|
+
When one fires, spend a sentence on the cause rather than the symptom. Agents
|
|
273
|
+
succeed in a **pit of success** — an environment where the wrong thing is hard
|
|
274
|
+
to express:
|
|
275
|
+
|
|
276
|
+
| Lever | Looks like |
|
|
277
|
+
|---|---|
|
|
278
|
+
| Constrained surface | a narrower type, a smaller public API, an argument that cannot be passed wrong |
|
|
279
|
+
| Rules that force correctness | a lint rule, a stricter compiler flag, a test that fails on the shape and not just the value |
|
|
280
|
+
| Written convention | a line in `AGENTS.md` / `CLAUDE.md` or the house-style skill, so a reviewer cites it instead of re-deriving it |
|
|
281
|
+
| Data the agent lacks | dev-server or production logs, a test database, browser access to watch the thing actually render |
|
|
282
|
+
|
|
283
|
+
**The output is a sentence to the user, or a backlog item — never a new
|
|
284
|
+
artifact.** Name the hardening and let the user decide. If a backlog skill
|
|
285
|
+
(`record`, or the repo's own convention) is installed and they want it kept,
|
|
286
|
+
file it there. Do not create a file for it, do not add a `.condux/` directory
|
|
287
|
+
for it, and do not implement it inside the current task — that is scope
|
|
288
|
+
expansion, which Escalating Mid-Task already forbids.
|
|
289
|
+
|
|
290
|
+
**Silence is the correct output when neither trigger fired.** A clean SMALL
|
|
291
|
+
task gets no hardening commentary at all.
|
|
292
|
+
|
|
256
293
|
## Red Flags
|
|
257
294
|
|
|
258
295
|
Stop if you catch yourself doing any of these:
|
|
@@ -269,7 +306,9 @@ Stop if you catch yourself doing any of these:
|
|
|
269
306
|
| Silently skipping discovery on a LARGE task | Ask — it's a soft gate, not a free pass |
|
|
270
307
|
| Rewriting a test spec to make it pass | Stop and ask — never silently edit specs |
|
|
271
308
|
| Auto-running code-review, commits, or agents | They're checkpoint choices; run only when picked |
|
|
309
|
+
| Verifying live without loading `live-verification` | Load it — its `report.md` is the evidence (9 of 11 ad-hoc runs in a mobile eval left none) |
|
|
272
310
|
| Auto-advancing past a checkpoint on MEDIUM/LARGE | The user owns every transition |
|
|
311
|
+
| Absorbing a workaround silently so the change lands | Name it — that's a hardening trigger, and preflight asks for it anyway |
|
|
273
312
|
| Expanding scope past the confirmed tier | Stop, report, re-confirm |
|
|
274
313
|
|
|
275
314
|
## Tips
|