Commit Graph
74 Commits
Author SHA1 Message Date
Nathan Schneider 7c2de2cefb docs: refresh img/ summary charts; add img index; cite reproducible stats
- Regenerated the three README charts from data/synthetic_1.2.6 via
  scripts/univariate_analysis.py --img (replaces the Feb 2026 ad-hoc versions)
- img/README.md: documents img/ as the published-docs chart directory
  (stable README link targets), with provenance and the regeneration command
- README: skew/mean narrative updated to the reproducible script output
  (mean 5.44, median 5.48; Fisher skew -0.03) with pointer to
  univariate_summary.txt, keeping the historical ODS reference
2026-10-02 08:47:30 -06:00
Nathan Schneider e100848a0d data: univariate averages outputs for the 1.2.6 run
Produced alongside the img/ chart refresh via scripts/univariate_analysis.py:
per-protocol and per-gradient averages tables, summary plots, and
univariate_summary.txt (mean 5.44, median 5.48, normalized midpoint
deviation 0.11).
2026-10-02 08:47:27 -06:00
Nathan Schneider ff19af5dd1 data: analysis outputs for the synthetic_1.4.0 run
Full pipeline per README command flow (steps 2-6): univariate averages and
distributions, multivariate analysis (2-cluster k-means: 209 relational vs
199 institutional; PCA/t-SNE/UMAP/factor/correlation/network/importance),
LDA separation and overlaid cluster plots, and LDA classifications (trained
on the 1.2.6 run via version-matched auto-selection). Cross-version summary
is on the console report: avg Euclidean distance 9.06 vs 1.2.6 (r=0.79).
2026-10-02 08:39:52 -06:00
Nathan Schneider 71c1977b77 docs: bicorder_model.json is research-only (app integration removed in v1.3.0)
Verified: bicorder-app has no classifier implementation and reads
bicorder_model.json nowhere (src, build config); ascii_bicorder.py doesn't
use it either. Corrected the stale 'read by bicorder-app at build time'
claims in README, WORKFLOW, and the export script docstring.
2026-10-02 08:39:26 -06:00
Nathan Schneider f136df46db Slight rewording in README for uniformity 2026-10-02 08:33:58 -06:00
Nathan Schneider 5a84408587 docs: command flow for analysis runs in README; keep WORKFLOW in sync
- README: new 'Command flow' section — dependency-ordered pipeline (setup →
  batch generation → univariate → multivariate → LDA/cluster visualizations →
  classify → cross-version compare → JSON/model export) with actual output
  paths per step, using data/synthetic_1.4.0/ as the example
- README: document chart production — univariate_analysis --img publishes the
  img/ summary charts; visualize_clusters added to the flow
- README: fix -b path in 'Adding a new run' (bicorder.json lives at repo root)
- WORKFLOW: script list and any-readings-CSV command block updated to match
2026-10-02 08:33:08 -06:00
Nathan Schneider 8c44064196 data: add synthetic_1.4.0 run readings
411 protocols × 23 gradients scored against bicorder.json v1.4.0 with
gpt-oss:20b-cloud (same analyst standpoint as the 1.2.6 run); the
bicorder_version column makes the run self-describing. Analysis outputs to
follow in data/synthetic_1.4.0/analysis/.
2026-10-02 08:33:03 -06:00
Nathan Schneider 55cbd6cd5d feat: version-agnostic analysis scripts with shared version helpers
- scripts/bicorder_common.py (new): single source of truth for historical
  gradient renames (COLUMN_RENAMES), version detection (bicorder_version col
  → version col → data/<type>_<version>/ dir convention), and training-CSV
  auto-selection (find_training_csv)
- classify_readings.py: auto-select training run by recorded bicorder version
  (excludes the input itself to avoid circular training), canonicalize old
  column names, version-mismatch warnings
- bicorder_classifier.py / export_model_for_js.py: share renames + dimension
  loader; instructive error when clustering results are missing;
  bicorder_version recorded in exported models
- compare_analyses.py: CLI (reference + comparison CSVs), rename
  canonicalization so runs of different versions align on shared gradients,
  Descriptor dedup (was silently skewing merges); legacy no-arg audit intact
- scripts/univariate_analysis.py (new): per-protocol/per-gradient averages,
  distributions, summary stats; --img publishes the three README summary
  charts to img/
- sync_readings.sh: defer classifier training to auto-matching; gitignore
  analysis/.venv and __pycache__
2026-10-02 08:32:59 -06:00
Nathan Schneider a4f16e8e4d Removed raw Claude outputs from README 2026-09-23 14:44:05 -06:00
Protocolbot 161ba3b136 fix: carry institutional→formal rename through analysis rename maps
Nathan renamed the Design gradient 'institutional' → 'formal' (v1.4.0).
The analysis scripts carry historical rename maps that route old data
(elite/institutional) into the current bicorder.json gradient names, and
those maps still stopped at 'institutional' — so old readings would have
silently misaligned against the v1.4.0 structure.

- bicorder_classifier.py / export_model_for_js.py: add
  institutional_vs_vernacular → formal_vs_vernacular, keep elite→formal
- json_to_csv.py TERM_RENAMES: same two-step route
- convert_csv_to_json.py GRADIENT_MAPPINGS: elite_vs_vernacular now maps
  to 'formal'
- bicorder_classifier.py demo ratings: use the current dimension name
- analysis/README.md: example run name 1.3.0 → 1.4.0
2026-09-23 14:27:51 -06:00
Protocolbot 6ae77a4f9b refactor: reorganize analysis data to support multiple runs
Strategy: key runs by bicorder version (not date), promote shared inputs
to analysis/data/, and stamp every output with its bicorder_version so
a re-run on edited gradients is self-describing.

Data layout:
- Promote the shared protocol inputs out of the run directory:
    analysis/data/protocols_edited.csv  (411 cleaned protocols)
    analysis/data/protocols_raw.csv     (774 un-cleaned entries)
- Rename the v1.2.6 synthetic run:
    data/synthetic_20251116/ -> data/synthetic_1.2.6/
  so the bicorder version it was scored against is explicit (gradient
  structure changes between versions make date-based names ambiguous)

Provenance:
- bicorder_analyze.py now writes a 'bicorder_version' column into every
  output readings.csv, recording which gradient structure produced it

Scripts:
- Update the real code defaults that pointed at the old run path
  (bicorder_classifier.py, classify_readings.py, sync_readings.sh,
  compare_analyses.py) and refresh docstring/help examples
- Remove a stray committed __pycache__/.pyc

Docs: analysis/README.md documents the new layout + how to add a run;
WORKFLOW.md, TEST_COMMANDS.md, INTEGRATION_GUIDE.md paths updated.
2026-09-23 14:23:17 -06:00
Nathan Schneider 459015fe17 Switched institutional > formal 2026-09-23 09:37:25 -06:00
Protocolbot e7d6465ceb docs: mark classifier integration historical; fix shortform count
- INTEGRATION_GUIDE.md: rewritten as research notes — how to reproduce the
  cluster classification with the analysis scripts, and why it was removed
  from the tool in v1.3.0
- analysis/README.md: integration section marked historical
- bicorder-app/README.md: shortform is 9 gradients, not 10
2026-09-23 07:58:17 -06:00
Protocolbot 8c40ca076b feat: remove formal/informal LDA analysis from the bicorder (v1.3.0)
The two-family cluster classification is a research finding, not a
diagnostic; embedding it in the tool caused recurring bugs:

- ascii_bicorder.py had an inverted LDA sign (institutional mapped to 9,
  not 1) and a stale term check ('bureaucratic') that silently disabled
  the calculation after the Feb 2026 rename — output was always null
- The web app and Python script had divergent sign conventions and
  divergent version-mismatch behavior (skip vs. continue with stale model)

Changes:
- bicorder.json: drop the formal/informal analysis gradient; version 1.3.0
- ascii_bicorder.py: remove all LDA/model machinery; keep hardness and
  polarization as the only automated analyses
- App.svelte: remove classifier import, model constant, LDA calculation,
  and form-recommendation reactive block; dispatch automated analyses by
  term_left instead of array index
- Delete bicorder-classifier.ts and FormRecommendation.svelte (the latter
  was imported but never rendered)
- AnalysisTransitionBanner: remove recommendation alert and prop; fix
  hardcoded index checks that referenced the removed gradient
- vite.config.ts / vite-env.d.ts: stop loading bicorder_model.json

The cluster classifier lives on as research in analysis/ (scripts and
model untouched there). bicorder.txt regenerated.
2026-09-23 07:58:11 -06:00
Protocolbot fb3bebcea0 fix: make --resume in batch pipeline actually skip completed work
Previously --resume re-queried every gradient in every row, overwriting
existing values — an interrupted run could not be resumed cheaply.

- bicorder_query.py: add --resume flag; skip gradients whose cells already
  have values, and report how many were skipped
- bicorder_batch.py: pass --resume through to query; skip fully-complete
  rows before invoking the query script; report partial rows
- bicorder_batch.py: import row/config helpers from bicorder_query instead
  of calling undefined names (would have crashed on --resume)
2026-09-23 07:58:04 -06:00
Nathan SchneiderandClaude Opus 4.8 c571bf1c01 Add landing screen as the app's entry point
Introduce a simple, show-don't-tell entry screen that lowers the "what
counts as a protocol" barrier and frames the activity as a short journey:

- Lead line "Examine the protocols around you" over a rotating, cross-fading
  list of deliberately diverse examples (traffic, code, kitchens, ritual,
  governance, play)
- Prominent "Begin" CTA above a three-step path: Describe / Understand / Share
- "About the Bicorder" link opens the existing help modal

Shown on first arrival; returning users with a reading in progress skip
straight to the diagnostic (computed synchronously, no flash). Remove the
now-redundant inline description from the focused flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 17:37:42 -06:00
Nathan SchneiderandClaude Opus 4.8 fd556d967f Fix inverted sign in formal/informal LDA analysis gradient
The model (analysis/bicorder_model.json) maps a positive LDA score to
cluster 2 = Institutional/Bureaucratic = "formal", but ldaScoreToScale
added the score (5 + score*4/3), sending formal/institutional protocols
toward 9 (informal) and vice versa. bicorder.json defines this gradient
as 1 = formal, 9 = informal, so the score must be subtracted.

- Flip the sign: value = 5 - (ldaScore * 4/3); correct the doc comment to
  state the model's actual sign convention
- Rename calculateBureaucratic -> calculateFormalInformal and update the
  stale analysisOrder comment, matching bicorder.json's formal/informal terms

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 16:36:01 -06:00
Nathan SchneiderandClaude Opus 4.8 f07708f296 Redesign gradient control as ASCII diverging-fill scale
Replace the click-anywhere ASCII bar (whose hit-mapping was offset from
the displayed marker, so taps registered the wrong value) with a track of
nine discrete, exact tap targets that fill from the center outward to the
selection: [----==#--]. Direction and distance from center read at a glance.

- Exact per-position selection on touch and desktop; no more position math
- Keyboard support (arrows/Home/End), scoped so it doesn't trigger
  the app-level screen navigation
- Center the bar and slim mobile padding so the full track fits narrow
  viewports
- Apply the same control to the manual analysis gradient; render the
  automated ones as a matching read-only, dimmed display
- Add a subtle gray "Value: #" indicator below the buttons on the
  diagnostic gradients, matching the analysis screens
- Move the "auto-calculated" note under the ANALYSIS header instead of
  after the value

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 16:02:16 -06:00
Nathan SchneiderandClaude Opus 4.8 12ac4eb943 Improve metadata prompts; fix upload error + remove debug log
- Replace bracketed metadata placeholders with prompting questions
- Fix upload error message (response.statusContents -> statusText)
- Remove stray debug console.log on reactive screen updates
- Document the upload token's security model in the app README

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-30 15:09:09 -06:00
ntnsndr 159221bfc9 Slight adjustment to institutional definition 2026-05-08 21:23:22 +00:00
Nathan SchneiderandClaude Sonnet 4.6 60e83783ec Flatten data/readings/ → data/
Remove the intermediate readings/ subdirectory level — dataset naming
(synthetic_YYYYMMDD, manual_YYYYMMDD) already encodes what the data is.
Update all path references across scripts and docs accordingly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 17:46:23 -06:00
Nathan SchneiderandClaude Sonnet 4.6 1a80219a25 Remove web/ prototype; update docs to reflect app integration
The web/ directory (bicorder-classifier.js, .d.ts, test-classifier.mjs)
was a prototype superseded by bicorder-app/src/bicorder-classifier.ts.
The only integration point between this analysis directory and the app is
bicorder_model.json, which Vite reads at build time.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 17:39:25 -06:00
Nathan SchneiderandClaude Sonnet 4.6 897c30406b Reorganize directory, add manual dataset and sync tooling
- Move all scripts to scripts/, web assets to web/, analysis results
  into self-contained data/readings/<type>_<YYYYMMDD>/ directories
- Add data/readings/manual_20260320/ with 32 JSON readings from
  git.medlab.host/ntnsndr/protocol-bicorder-data
- Add scripts/json_to_csv.py to convert bicorder JSON files to CSV
- Add scripts/sync_readings.sh for one-command sync + re-analysis of
  any dataset backed by a .sync_source config file
- Add scripts/classify_readings.py to apply the LDA classifier to all
  readings and save per-reading cluster assignments
- Add --min-coverage flag to multivariate_analysis.py for sparse/shortform
  datasets; also applies in lda_visualization.py
- Fix lda_visualization.py NaN handling and 0-d array annotation bug
- Update README.md and WORKFLOW.md to document datasets, sync workflow,
  shortform handling, and new scripts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 17:35:13 -06:00
Nathan SchneiderandClaude Sonnet 4.6 0c794dddae Improve layout responsiveness on narrow windows
Prevent horizontal overflow with overflow-x: hidden on body. Make the
gradient bar fill its container in focused mode (width: 100%;
min-width: 0) rather than holding a fixed minimum width.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 15:56:58 -06:00
Nathan SchneiderandClaude Sonnet 4.6 721b588a2b Fix layout cutoff on narrow desktop windows
Raise responsive layout breakpoints from 768px to 900px across all
components. This ensures narrow desktop browser windows (769–900px)
get the stacked, single-column layout rather than the three-column
grid that was too wide for those widths. The 768px breakpoint in
app.css is kept as-is since it only adjusts font sizes for iOS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 15:27:59 -06:00
Nathan SchneiderandClaude Sonnet 4.6 f1ae9cac1f Derive classifier dimensions from bicorder.json automatically
Both export_model_for_js.py and bicorder_classifier.py now read
DIMENSIONS and KEY_DIMENSIONS directly from bicorder.json at runtime,
so the model stays in sync whenever gradient terms are renamed or
added. A COLUMN_RENAMES dict handles historical CSV column name
changes. The model now includes bicorder_version so the app's version
check works correctly.

Regenerated bicorder_model.json against bicorder.json v1.2.6 with
correct dimension names, 9 key dimensions from shortform flags, and
updated thresholds.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 15:13:54 -06:00
Nathan SchneiderandClaude Sonnet 4.6 5232e760be Update help/about text
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 15:12:19 -06:00
Nathan SchneiderandClaude Sonnet 4.6 50b7821596 Allow text selection in the interface
Remove user-select: none from body, keeping it only on interactive
elements (buttons, sliders, tooltips) where it prevents accidental
selection during interaction.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 14:31:43 -06:00
Nathan SchneiderandClaude Sonnet 4.6 4589fba64e Fix upload dialog visibility and mobile overflow
Move the upload confirmation dialog above the action buttons so it's
immediately visible, and add overflow-safe CSS to prevent text from
spilling outside the dialog box on mobile.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-20 13:59:19 -06:00
Nathan Schneider 730075f757 Tweaks to analysis readme 2026-03-03 20:42:07 -07:00
Nathan Schneider 61dac6ff28 Changed major LDA category names 2026-02-21 17:25:22 -07:00
Nathan Schneider 62a6b0ba2c analysis updates 2026-02-21 17:13:15 -07:00
Nathan Schneider b004e9fb19 Analysis changes 2026-01-25 22:55:30 -07:00
Nathan Schneider 900ec1a6af Merge branch 'main' of https://git.medlab.host/ntnsndr/protocol-bicorder 2026-01-25 22:54:32 -07:00
Nathan Schneider 57b780fe95 Additional analysis in app and tweaked json descriptions 2026-01-25 22:48:54 -07:00
ntnsndr 6209990436 Updated README ASCII 2026-01-19 22:04:12 +00:00
Nathan Schneider f53ada8196 User experience improvements to the focused mode 2026-01-18 16:59:56 -07:00
Nathan Schneider 56d1f7e11e Improved analysis screen on focused mode. 2026-01-17 22:58:24 -07:00
Nathan Schneider d1f288cda8 Adjusted the classifier to reduce false flags 2026-01-14 22:44:32 -07:00
Nathan Schneider 6230e6da7b Added arrows to focused view for clarity 2026-01-14 22:35:27 -07:00
Nathan Schneider 3355ed9f02 Added synthetic_readings JSON files to analysis 2026-01-14 21:59:28 -07:00
Nathan Schneider 7829141756 Analysis updates and json tweaks 2026-01-14 21:42:23 -07:00
Nathan Schneider 1b508b911f Added classifer analysis to bicorder ascii and web app 2025-12-21 21:38:39 -07:00
Nathan Schneider b541f85553 Additional analysis: examining clustering via LDA 2025-12-19 11:40:45 -07:00
Nathan Schneider d62d9205ac Updated logo/icon 2025-12-18 13:38:44 -07:00
Nathan Schneider cbcb06ff01 Added Description support to bicorder.txt 2025-12-18 11:10:14 -07:00
Nathan Schneider 7914f14807 Adjusted some terms 2025-12-18 11:06:38 -07:00
Nathan Schneider 2827c9c7f4 Removed unnecessary Value field on web app 2025-12-18 11:03:47 -07:00
Nathan Schneider 7a57c29202 Updated ASCII slider interface 2025-12-18 10:44:15 -07:00
Nathan Schneider b461d759e5 Set short-form as default 2025-12-18 10:30:47 -07:00