/** * Rotation threshold, in bytes — 512 KB, the SAME number and the same `.1.log` naming as * decision-log.ts / rejection-log.ts / main-sync-log.ts. Deliberately identical rather than merely * similar: two log families in one directory with two different retention rules is a trap for whoever * later tries to reason about how much history they still have. */ export declare const SHIM_LOG_MAX_BYTES: number; /** * One verdict label the shim can record, WITH what it means. Data-only → a class, per CLAUDE.md. * * The meaning travels with the label because guards/L0-tooling.md renders this table rather than * restating it: a bare `string[]` left the meanings in prose, and the prose is what went stale (the * hand-written doc documented `DENY-UNDECLARED` for releases while this array did not list it at all). */ export declare class ShimLogVerdict { readonly label: string; readonly means: string; constructor(label: string, means: string); } /** * The verdict vocabulary one shim invocation can record, and how each maps to guards/L0-tooling.md. * * The ALLOW-* and DENY-* labels are the ones this log has always used and are kept verbatim, so * anything already grepping them keeps working. `PASS-BIN-*` is the healthy case the log used to be * silent about, and `DENY-UNDECLARED` is fault U's — emitted by the shim since U existed, but missing * from this array until the generated doc started reading it. */ export declare const SHIM_LOG_VERDICTS: readonly ShimLogVerdict[]; /** * The sh-side L0 fault codes, IMPORTED from the one codebook (../core/l0-fault-codes) rather than * retyped here — the letters in this file and the letters in `L0_FAULTS` have to be the same letters or * the log cannot be reconciled against the matrix. `-` means "no sh-side fault": the shim cannot * classify S / C / Y, which the BINARY detects and stamps onto its OWN streams with the same `fault=` * field, so a `-` here is a statement about this layer only, never a claim that nothing was wrong. */ export declare const SHIM_LOG_FAULTS: readonly ["D", "X", "U", "K", "-"]; /** * One FIELD of the audit line: how it reads on disk, the sh expression that produces it, and what it * answers. Data-only → a class, per CLAUDE.md. */ export declare class ShimLogField { readonly label: string; /** The sh word spliced into the printf below — the ONE place this field's value is spelled. */ readonly shValue: string; readonly means: string; /** * True for a field that is printed only SOMETIMES (`bin=`, and only when it differs from * `shim=`). Such a field carries its OWN trailing tab in its sh value and therefore renders * with NO separator of its own — `%s%s` glues it to the next field, so an empty value leaves * the line one field shorter rather than leaving a stray tab behind. */ readonly optional: boolean; constructor(label: string, /** The sh word spliced into the printf below — the ONE place this field's value is spelled. */ shValue: string, means: string, /** * True for a field that is printed only SOMETIMES (`bin=`, and only when it differs from * `shim=`). Such a field carries its OWN trailing tab in its sh value and therefore renders * with NO separator of its own — `%s%s` glues it to the next field, so an empty value leaves * the line one field shorter rather than leaving a stray tab behind. */ optional?: boolean); } /** * THE LINE, as data. The printf below is BUILT from this array and guards/L0-tooling.md RENDERS it, so * a field cannot be added, dropped or reordered without both the shim and the doc changing with it. * * That is not decoration: `shim=`/`bin=` were inserted mid-line (deliberately breaking positional * readers rather than appending where a stale parser keeps working), then `layer=`/`row=` joined them, * and the hand-written doc went on describing a 7-field line with no `U` in its fault set the whole time. */ export declare const SHIM_LOG_FIELDS: readonly ShimLogField[]; /** * The writer's `printf`, assembled from SHIM_LOG_FIELDS — one `%s` per field, in the same order, and a * tab after every field EXCEPT an optional one (which carries its own). Retyping either half is what * let the format and its documentation disagree, so neither half is retyped anywhere. */ export declare const SHIM_LOG_PRINTF: string; /** * Shell fragment: derive WHERE this call's log belongs — the sh TWIN of `DotWebpieces.local()` + * `worktreeName()` + `primaryRoot()` in @webpieces/rules-config. * * sh cannot import TypeScript, so this derivation is duplicated by necessity; the mitigation is * `shim-audit-log.spec.ts`, which runs THIS function through a real /bin/sh in real git worktrees and * asserts it returns exactly what `dotWebpieces.worktreeName()` returns. If the two ever disagree the * lock goes red rather than the logs quietly splitting in half. * * It asks git the SAME question the TS side asks — `--git-dir` vs `--git-common-dir`, which differ if * and only if this is a linked worktree — but in ONE `rev-parse` (it accepts both flags and prints a * line each) rather than two, because this runs on the blocking path of every tool call. * * The tree is derived from the PAYLOAD's `cwd` (Claude Code documents it as the working directory the * hook was invoked from), not from `$ROOT`. `$ROOT` is where the shim FILE lives and stays the anchor * for what the drift guard MEASURES — this fragment changes only where the log is WRITTEN. * * Fails soft, exactly like the TS side: when git cannot answer, the log collapses to * `/.webpieces/logs`, which is the pre-change behaviour. */ export declare const RESOLVE_LOG_DIR_SH = "wp_resolve_log_dir() {\n _wp_rp=\"$(git -C \"$WP_CWD\" rev-parse --git-dir --git-common-dir 2>/dev/null)\"\n _wp_gd=\"$(printf '%s\\n' \"$_wp_rp\" | sed -n 1p)\"\n _wp_cd=\"$(printf '%s\\n' \"$_wp_rp\" | sed -n 2p)\"\n if [ -z \"$_wp_gd\" ] || [ -z \"$_wp_cd\" ]; then\n WP_TREE=primary; WP_LOG_DIR=\"$WP_CWD/.webpieces/logs\"\n WP_PRIMARY_LOG_DIR=\"$WP_LOG_DIR\"; return 0\n fi\n # git prints a BARE .git from the primary clone and an absolute path from a linked worktree; the TS\n # twin runs path.resolve(cwd, printed), so do the same before comparing or taking a basename.\n case \"$_wp_gd\" in /*) : ;; *) _wp_gd=\"$WP_CWD/$_wp_gd\" ;; esac\n case \"$_wp_cd\" in /*) : ;; *) _wp_cd=\"$WP_CWD/$_wp_cd\" ;; esac\n # The primary clone's root is the parent of the SHARED git dir \u2014 declining any layout whose shared\n # dir is not named .git (a bare repo, --separate-git-dir), same test as primaryRoot().\n _wp_primary=\"$WP_CWD\"\n case \"$_wp_cd\" in\n */.git) [ -d \"${_wp_cd%/*}\" ] && _wp_primary=\"${_wp_cd%/*}\" ;;\n esac\n # The PRIMARY clone's log dir, resolved on both branches. A deny that has to tell a human WHERE the\n # audit trail is (the inverse-drift escalation in shim.ts) must be able to name both the tree it is\n # standing in and the primary \u2014 a subagent has no reach into the second one, so the deny has to quote\n # that path rather than send anyone to go and look.\n WP_PRIMARY_LOG_DIR=\"$_wp_primary/.webpieces/logs\"\n if [ \"$_wp_gd\" = \"$_wp_cd\" ]; then\n WP_TREE=primary\n WP_LOG_DIR=\"$WP_PRIMARY_LOG_DIR\"\n else\n # git's OWN name for the worktree (the basename of /.git/worktrees/), not the\n # directory's basename \u2014 two worktrees under different parents may share a directory name.\n WP_TREE=\"${_wp_gd##*/}\"\n WP_LOG_DIR=\"$_wp_primary/.webpieces/worktrees/$WP_TREE/logs\"\n fi\n}"; /** * Shell fragment: the audit-log writer itself — `wp_log `, one tab-separated line. * * FORMAT: SHIM_LOG_FIELDS, tab-separated, append-only — that array IS the format, and SHIM_LOG_PRINTF * is built from it, so neither this docblock nor guards/L0-tooling.md can describe a line the shim does * not write. * * `tree=` and `fault=` are the two fields that make the file reconcilable against guards/L0-tooling.md: * the first says WHICH checkout produced the line (a shared log across seven worktrees is otherwise * unreadable), the second says which of the sh-side faults the shim detected. The verdict * keeps its historical spelling and stays adjacent to the command, so `grep 'DENY-STALE\\t'` still * finds what it always found. * * NEVER breaks or blocks the hook: the whole body is wrapped so a failure of any kind — unwritable * directory, read-only filesystem, missing `git` — is swallowed, and nothing is ever written to * stdout (stdout is the PreToolUse decision channel; a stray byte there corrupts allow/deny). * * The log dir is resolved LAZILY on first use so a call that never logs never pays for the git probe. */ export declare const WP_LOG_SH: string;