feat(linkedin-studio): N14 — foldIns-fangst + Step 11 retro + background-headless + språkregel-akkumulering [skip-docs]
Lukker sløyfen pluginen manglet: en rettelse operatøren gjør i utgave N håndheves i N+1 i stedet for å bli gjenoppdaget. Maskineriet fantes (foldIns-skjema + promote→ratify siden fix #1); det som manglet var wiring — ingenting skrev til køen og ingen fase tømte den. - Fangst (A2-F7): Steps 2.5/3a/5.5/6.5 appender rettelsen ordrett med trigger, decision "pending". Ubetinget og bevisst dum — å avgjøre ved fangst om noe "fortjener" en regel er nettopp slik køen holder seg tom og sløyfen dør. - Step 11 retro (A2-F8), ≤5 min ETTER scheduling: promoter køen med eksplisitt JA/NEI (mekanisk → atomisk contract-gate-promotering, teller kun med grønn --ratify; dømmekraft → operatørens språkregelfil; NEI → rejected, beholdes), effort-oppsummering fra MÅLT phaseLog (aldri re-estimert), og ÉN friksjons-spørring som besvares tilbake til operatøren. Faser 18 → 19; resumption-tabellen ruter scheduling → Step 11, retro → complete. - articles.NN.retro: additiv-valgfri (default null), schemaVersion forblir 1. - Background-headless (A2-F6): --background kjører pakken i en bakgrunnsagent som skriver rapporten til disk; drafting-sesjonen leser fila. Samme isolasjon som fersk sesjon, uten copy-paste-sømmen. Inline fan-out = eksplisitt fallback. - Språkregler (C-10): ${DATA}/language-rules/<lang>.md (opt-in, template). Leses TO ganger — av language-reviewer (fanger) og av Step 4 (forebygger). Shippet banliste forblir baseline; brukerfila utvider. - references/fold-in-loop.md (A2-F9): loopen dokumentert domene-generelt in-tree, så en adopter uten ekstern skrivekontrakt har hele sløyfen. Refs 28 → 29. Suiter (alle grønne): test-runner 197 → 217 (Section 16u: 18 ubetingede greps + non-vacuity self-test; fase-sveip 16 → 17 faser; floor 179 → 198) · hooks 174 · trends 300 · brain 134 · editions 72 · specifics-bank 45 · contract-gate 33 · tests 35 · render 60. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QxvWAjte7vPcF79QeSRvRJ
This commit is contained in:
parent
677eab9294
commit
f0532dce3f
9 changed files with 711 additions and 30 deletions
|
|
@ -100,7 +100,7 @@ warn() { echo -e "${YELLOW}⚠${NC} $1"; WARN=$((WARN + 1)); }
|
|||
# with the files when adding/removing an agent, command, reference, or skill.
|
||||
EXPECT_AGENTS=20
|
||||
EXPECT_COMMANDS=30
|
||||
EXPECT_REFS=28
|
||||
EXPECT_REFS=29
|
||||
EXPECT_SKILLS=6
|
||||
# Pre-M0 references/ baseline was 25. Every ref doc added since is NAMED below, so the
|
||||
# count bump always maps to an intended, named addition — never an incidental doc masked
|
||||
|
|
@ -112,6 +112,7 @@ M0_REF="references/data-path-convention.md"
|
|||
POSTM0_REFS=(
|
||||
"references/trend-scoring-modes.md" # research-engine slice 2a (scoring SSOT)
|
||||
"references/figure-design-guidelines.md" # MR-F4 N3 (coded-figure design rules + token convention)
|
||||
"references/fold-in-loop.md" # N14 A2-F9 (capture->classify->promote->enforce, domain-general)
|
||||
)
|
||||
|
||||
echo "================================================"
|
||||
|
|
@ -1996,13 +1997,14 @@ NL_FLAT=$(tr '\n' ' ' < "$NL_N12" | tr -s ' ')
|
|||
MISSING_PHASES=""
|
||||
for phase in lived-specifics research skeleton-pitch spine-prose draft consistency-quality \
|
||||
contract-gate factcheck-sweep editorial-review persona-sweep-prelock \
|
||||
headless-review annotation visual-assets lock-delivery hook-conversion-gate scheduling; do
|
||||
headless-review annotation visual-assets lock-delivery hook-conversion-gate scheduling \
|
||||
retro; do
|
||||
if ! printf '%s' "$NL_FLAT" | grep -qF "run the protocol (Step 0) for ${BT}${phase}${BT}"; then
|
||||
MISSING_PHASES="$MISSING_PHASES $phase"
|
||||
fi
|
||||
done
|
||||
if [ -z "$MISSING_PHASES" ]; then
|
||||
pass "all 16 canonical phases carry a transition call - the lead-time log has no holes (A1-12)"
|
||||
pass "all 17 canonical phases carry a transition call - the lead-time log has no holes (A1-12)"
|
||||
else
|
||||
fail "newsletter phases with no transition call:$MISSING_PHASES - lead time silently undercounts them (A1-12)"
|
||||
fi
|
||||
|
|
@ -2194,6 +2196,202 @@ fi
|
|||
|
||||
echo ""
|
||||
|
||||
# --- Section 16u: Fold-In Loop + Retro Step (N14 / A2-F6,F7,F8,F9, C-10) ---
|
||||
echo "--- Fold-In Loop + Retro (N14) ---"
|
||||
|
||||
# N14 closes the loop the whole pipeline was missing: a correction the operator makes in
|
||||
# edition N is ENFORCED in edition N+1 instead of being re-discovered. The machinery already
|
||||
# existed (foldIns schema + promote->ratify); what was absent was the wiring - nothing wrote
|
||||
# to the queue and no step ever emptied it. So the bindings worth linting are:
|
||||
# (A2-F7 capture) every step where the operator corrects prose appends to the queue - a
|
||||
# compound predicate (queue named + left open + routed), so a non-vacuity
|
||||
# self-test guards it (mirrors Sections 16p/16q/16r/16s/16t).
|
||||
# (A2-F8 retro) Step 11 exists and does all three jobs: promote the queue, summarize the
|
||||
# measured effort (phaseLog, N12), ask ONE friction question.
|
||||
# (A2-F6 headless) the cold package runs as a background agent writing to a file - the
|
||||
# maximum-independence path with no manual copy-paste seam.
|
||||
# (C-10 language) confirmed language corrections accumulate in a USER file the reviewer
|
||||
# and the drafting step both read - the shipped ban-list stays the baseline.
|
||||
# (A2-F9 adopter) the fang->klassifiser->promoter->handhev loop is documented in-tree, so
|
||||
# an adopter without the author's contract still has the whole loop.
|
||||
NL_N14="commands/newsletter.md"
|
||||
HR_N14="commands/headless-review.md"
|
||||
LR_N14="agents/language-reviewer.md"
|
||||
EST_N14="config/edition-state.template.json"
|
||||
LANG_TPL="config/language-rules.template.md"
|
||||
FOLDIN_REF="references/fold-in-loop.md"
|
||||
|
||||
foldin_capture_wired() { # $1 = text; wired iff it NAMES the queue, leaves it OPEN, and ROUTES it
|
||||
echo "$1" | grep -qF "foldIns" \
|
||||
&& echo "$1" | grep -qF "pending" \
|
||||
&& echo "$1" | grep -qF "Step 11"
|
||||
}
|
||||
|
||||
FI_SELFTEST_OK=1
|
||||
if ! foldin_capture_wired "append the correction to articles.NN.foldIns with decision pending; Step 11 routes it"; then
|
||||
FI_SELFTEST_OK=0; echo " non-vacuity FAIL: a fully-wired fold-in-capture probe was not detected"
|
||||
fi
|
||||
while IFS= read -r probe; do
|
||||
[ -z "$probe" ] && continue
|
||||
if foldin_capture_wired "$probe"; then
|
||||
FI_SELFTEST_OK=0; echo " false-positive FAIL: under-wired fold-in-capture probe accepted -> $probe"
|
||||
fi
|
||||
done <<'NEGATIVE16U'
|
||||
append the correction to articles.NN.foldIns with decision pending, routed by nobody
|
||||
capture the correction as pending and let Step 11 route it, queue left unnamed
|
||||
append it to articles.NN.foldIns and Step 11 promotes it, never marked open
|
||||
NEGATIVE16U
|
||||
if [ "$FI_SELFTEST_OK" -eq 1 ]; then
|
||||
pass "fold-in-capture self-test: predicate needs foldIns + pending + Step 11 (1 accepted, 3 under-wired rejected)"
|
||||
else
|
||||
fail "fold-in-capture self-test failed - the N14 wiring lint is vacuous or over-eager"
|
||||
fi
|
||||
|
||||
# (A2-F7 capture) each of the four fold-in steps feeds the queue - a step that folds a
|
||||
# correction in without capturing it is exactly how a rule gets re-discovered next edition
|
||||
STEP25_N14=$(awk '/^## Step 2.5:/{f=1} /^## Step 3a:/{f=0} f' "$NL_N14")
|
||||
STEP3A_N14=$(awk '/^## Step 3a:/{f=1} /^## Step 3b:/{f=0} f' "$NL_N14")
|
||||
STEP55_N14=$(awk '/^## Step 5.5:/{f=1} /^## Step 6:/{f=0} f' "$NL_N14")
|
||||
STEP65_N14=$(awk '/^## Step 6.5:/{f=1} /^## Step 7:/{f=0} f' "$NL_N14")
|
||||
STEP11_N14=$(awk '/^## Step 11:/{f=1} /^## Distribution channel/{f=0} f' "$NL_N14")
|
||||
|
||||
if foldin_capture_wired "$STEP25_N14"; then
|
||||
pass "Step 2.5 captures operator corrections into the fold-in queue (A2-F7)"
|
||||
else
|
||||
fail "newsletter Step 2.5 folds annotations in without capturing them - the rule is lost (A2-F7)"
|
||||
fi
|
||||
|
||||
if foldin_capture_wired "$STEP3A_N14"; then
|
||||
pass "Step 3a captures operator corrections into the fold-in queue (A2-F7)"
|
||||
else
|
||||
fail "newsletter Step 3a folds annotations in without capturing them - the rule is lost (A2-F7)"
|
||||
fi
|
||||
|
||||
if foldin_capture_wired "$STEP55_N14"; then
|
||||
pass "Step 5.5 captures approved editorial flags into the fold-in queue (A2-F7)"
|
||||
else
|
||||
fail "newsletter Step 5.5 folds flags in without capturing them - the rule is lost (A2-F7)"
|
||||
fi
|
||||
|
||||
if foldin_capture_wired "$STEP65_N14"; then
|
||||
pass "Step 6.5 captures approved cold-review flags into the fold-in queue (A2-F7)"
|
||||
else
|
||||
fail "newsletter Step 6.5 folds flags in without capturing them - the rule is lost (A2-F7)"
|
||||
fi
|
||||
|
||||
# (A2-F8 retro) the step exists and empties the queue with an explicit operator verdict
|
||||
if echo "$STEP11_N14" | grep -qF "foldIns" && echo "$STEP11_N14" | grep -qF "promoted"; then
|
||||
pass "Step 11 promotes the fold-in queue with an operator verdict (A2-F8)"
|
||||
else
|
||||
fail "newsletter has no Step 11 fold-in promotion - the queue fills up and is never emptied (A2-F8)"
|
||||
fi
|
||||
|
||||
# (A2-F8 effort) the effort summary reads the MEASURED log (N12), not the model's memory
|
||||
if echo "$STEP11_N14" | grep -qF "phaseLog"; then
|
||||
pass "Step 11 summarizes effort from the measured phaseLog - no new measuring apparatus (A2-F8/A1-12)"
|
||||
else
|
||||
fail "newsletter Step 11 does not read phaseLog - effort is re-estimated from memory (A2-F8)"
|
||||
fi
|
||||
|
||||
# (A2-F8 friction) exactly one friction question, and the operator's own register stays theirs
|
||||
if echo "$STEP11_N14" | grep -qF "process friction" && echo "$STEP11_N14" | grep -qF "never write"; then
|
||||
pass "Step 11 asks one friction question and never writes the operator's register (A2-F8)"
|
||||
else
|
||||
fail "newsletter Step 11 lacks the single friction question or claims write access to the operator's register (A2-F8)"
|
||||
fi
|
||||
|
||||
# (A2-F8 transition) retro is a real phase - logged like every other, and it re-closes the row
|
||||
if echo "$STEP11_N14" | grep -qF "register-complete" && echo "$STEP11_N14" | grep -qF "${BT}retro${BT}"; then
|
||||
pass "Step 11 runs the retro transition and re-closes the register row (A1-11/A2-F8)"
|
||||
else
|
||||
fail "newsletter Step 11 leaves the edition re-opened in the register or logs no retro phase (A1-11/A2-F8)"
|
||||
fi
|
||||
|
||||
# (A2-F8 schema) edition-state documents AND carries the retro slot
|
||||
if grep -qF '"retro": "Per-article retro record' "$EST_N14" && grep -qF '"retro": null' "$EST_N14"; then
|
||||
pass "edition-state documents and carries the per-article retro slot (A2-F8 schema)"
|
||||
else
|
||||
fail "$EST_N14 has no documented retro slot - the retro leaves no durable record (A2-F8)"
|
||||
fi
|
||||
|
||||
# (A2-F8 resumption) an edition aborted after scheduling resumes INTO the retro, not past it
|
||||
RESUME_N14=$(awk '/^### Deterministic resumption/{f=1} /^### Phase-transition protocol/{f=0} f' "$NL_N14")
|
||||
if echo "$RESUME_N14" | grep -qF "Step 11" && echo "$RESUME_N14" | grep -qF "${BT}retro${BT}"; then
|
||||
pass "resumption table routes scheduling -> Step 11 and retro -> complete (A2-F8)"
|
||||
else
|
||||
fail "newsletter resumption table skips the retro - an aborted session drops the fold-in queue (A2-F8)"
|
||||
fi
|
||||
|
||||
# (A2-F6 headless) the cold package can run as a background agent writing its report to a file
|
||||
if grep -qF "run_in_background" "$HR_N14" && grep -qF -- "--background" "$HR_N14"; then
|
||||
pass "headless-review offers a background run - cold isolation without a fresh session (A2-F6)"
|
||||
else
|
||||
fail "$HR_N14 has no background mode - maximum independence still costs a manual session switch (A2-F6)"
|
||||
fi
|
||||
|
||||
if grep -qF "no copy-paste" "$HR_N14"; then
|
||||
pass "headless-review states the seam it removes - the report is read from disk, not pasted (A2-F6)"
|
||||
else
|
||||
fail "$HR_N14 still relies on pasting the report back into the drafting session (A2-F6)"
|
||||
fi
|
||||
|
||||
# (A2-F6 wiring) Step 6.5 actually offers that path instead of the paste-back one
|
||||
if echo "$STEP65_N14" | grep -qF -- "--background"; then
|
||||
pass "newsletter Step 6.5 routes maximum-independence through the background run (A2-F6)"
|
||||
else
|
||||
fail "newsletter Step 6.5 still sends the operator to a fresh session with a paste-back (A2-F6)"
|
||||
fi
|
||||
|
||||
# (C-10 language) the accumulating user file is READ by the reviewer and by the drafting step
|
||||
if grep -qF "language-rules/" "$LR_N14"; then
|
||||
pass "language-reviewer reads the accumulated user language rules (C-10)"
|
||||
else
|
||||
fail "$LR_N14 grades only against the shipped list - confirmed corrections never bind (C-10)"
|
||||
fi
|
||||
|
||||
STEP4_N14=$(awk '/^## Step 4: /{f=1} /^## Step 4.5:/{f=0} f' "$NL_N14")
|
||||
if echo "$STEP4_N14" | grep -qF "language-rules/"; then
|
||||
pass "newsletter Step 4 reads the accumulated user language rules while drafting (C-10)"
|
||||
else
|
||||
fail "newsletter Step 4 ignores the accumulated language rules - they only catch, never prevent (C-10)"
|
||||
fi
|
||||
|
||||
if echo "$STEP11_N14" | grep -qF "language-rules/"; then
|
||||
pass "Step 11 appends confirmed language corrections to the user rules file (C-10)"
|
||||
else
|
||||
fail "newsletter Step 11 never writes the language-rules file - judgment corrections evaporate (C-10)"
|
||||
fi
|
||||
|
||||
# (C-10 opt-in) the file is offered as a template, never written for the user (slots pattern)
|
||||
if [ -f "$LANG_TPL" ] && grep -qF "OPT-IN" "$LANG_TPL"; then
|
||||
pass "language-rules template ships with an explicit opt-in - nothing is imposed (C-10/de-niche)"
|
||||
else
|
||||
fail "$LANG_TPL missing or does not state the opt-in (C-10/de-niche)"
|
||||
fi
|
||||
|
||||
# (A2-F9 adopter) the whole loop is documented in-tree, all four stages named
|
||||
FOLDIN_LOOP_OK=1
|
||||
for stage in "Capture" "Classify" "Promote" "Enforce"; do
|
||||
grep -qF "$stage" "$FOLDIN_REF" 2>/dev/null || FOLDIN_LOOP_OK=0
|
||||
done
|
||||
if [ -f "$FOLDIN_REF" ] && [ "$FOLDIN_LOOP_OK" -eq 1 ]; then
|
||||
pass "fold-in loop documented in-tree with all four stages (A2-F9)"
|
||||
else
|
||||
fail "$FOLDIN_REF missing or does not name capture/classify/promote/enforce (A2-F9)"
|
||||
fi
|
||||
|
||||
# (A2-F9 self-contained) an adopter without the author's private contract still has the loop,
|
||||
# and the four accumulation silos are named as one collection point
|
||||
if grep -qF "not a gap" "$FOLDIN_REF" 2>/dev/null \
|
||||
&& grep -qF "specifics-bank" "$FOLDIN_REF" 2>/dev/null \
|
||||
&& grep -qF "ab-test" "$FOLDIN_REF" 2>/dev/null; then
|
||||
pass "fold-in loop is adopter-self-contained and names the accumulation silos (A2-F9)"
|
||||
else
|
||||
fail "$FOLDIN_REF reads as requiring the author's private contract, or omits the silos (A2-F9)"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
|
||||
# --- Section 18: Assertion-Count Anti-Erosion (SC6) ---
|
||||
# The lint self-modifies its own checks, so a green run could mask a silently dropped
|
||||
# assertion. Pin the total pass()+fail() invocations as a monotonic floor; the count
|
||||
|
|
@ -2245,12 +2443,19 @@ echo ""
|
|||
# wiring grep + calendar opt-in grep + session-start two-block compound grep + coverage
|
||||
# queue+register grep + data-dir placement grep + Step-10 nextFreeSlot grep + Step-10 --slot
|
||||
# grep + scheduling-ref directional grep + scheduling-ref operator-grid grep + slot-template
|
||||
# schema/opt-in grep + de-niche no-hardcoded-times/no-committed-grid check) = 179.
|
||||
# schema/opt-in grep + de-niche no-hardcoded-times/no-committed-grid check) = 179; +19 for
|
||||
# N14's nineteen UNCONDITIONAL Section-16u checks (fold-in-capture self-test + four capture
|
||||
# greps for Steps 2.5/3a/5.5/6.5 + Step-11 promotion grep + Step-11 phaseLog grep + Step-11
|
||||
# friction/never-write grep + Step-11 retro-transition/re-close grep + edition-state retro
|
||||
# doc+slot grep + resumption retro-routing grep + headless background-mode grep + headless
|
||||
# no-copy-paste grep + Step-6.5 background-routing grep + language-reviewer rules-file grep +
|
||||
# Step-4 rules-file grep + Step-11 rules-file append grep + language-rules template opt-in
|
||||
# check + fold-in-loop four-stage check + fold-in-loop adopter/silos grep) = 198.
|
||||
# NB: the floor tracks the deps-absent MINIMUM (conditional TS suites warn-skip and drop
|
||||
# the count), so it is bumped only by UNCONDITIONAL new checks — NOT pinned to the
|
||||
# deps-present TOTAL_CHECKS (that would zero the warn-skip margin and false-fail a fresh
|
||||
# clone). Runs last so TOTAL_CHECKS sees every prior check.
|
||||
ASSERT_BASELINE_FLOOR=179
|
||||
ASSERT_BASELINE_FLOOR=198
|
||||
TOTAL_CHECKS=$((PASS + FAIL))
|
||||
if [ "$TOTAL_CHECKS" -ge "$ASSERT_BASELINE_FLOOR" ]; then
|
||||
pass "assertion-count anti-erosion: $TOTAL_CHECKS checks >= baseline floor $ASSERT_BASELINE_FLOOR"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue